diff options
23 files changed, 465 insertions, 131 deletions
diff --git a/build/apex/Android.bp b/build/apex/Android.bp index d5349b6229..5b419e5415 100644 --- a/build/apex/Android.bp +++ b/build/apex/Android.bp @@ -630,3 +630,53 @@ linker_config { src: "linker.config.json", installable: false, } + +// sdk module types have 3 (maybe 4 for windows?) variants: linux, android, and common_os. +// common_os depends on the linux/android variants and packages their artifacts into a zip file. +// We want access to that zip file in art_release_zip, so we need to depend on only the common_os +// variant of art-module-host-exports, which is what sdk_genrule does. Since sdk_genrule only has +// 1 variant, we can then depend on it from a different type of genrule like regular genrule. +sdk_genrule { + name: "art-module-host-exports-for-genrule", + defaults: ["art_module_source_build_genrule_defaults"], + srcs: [":art-module-host-exports"], + out: ["art-module-host-exports-current.zip"], + cmd: "cp $(in) $(out)", +} + +// A zip containing ART binaries and ART bootclasspath jars. +// At the time of writing, this is only for Compiler Explorer (https://godbolt.org). +genrule { + name: "art_release_zip", + defaults: ["art_module_source_build_genrule_defaults"], + srcs: [ + ":art-module-host-exports-for-genrule", + ":com.android.art", + ], + out: [ + "art_release.zip", + ], + tools: [ + "deapexer", + "debugfs", + "fsck.erofs", + "merge_zips", + "soong_zip", + ], + cmd: "$(location deapexer) " + + "--debugfs_path $(location debugfs) " + + "--fsckerofs_path $(location fsck.erofs) " + + "extract $(location :com.android.art) $(genDir)/extracted && " + + + "$(location soong_zip) -o $(out).tmp -P bootjars -j " + + "-f $(genDir)/extracted/javalib/core-oj.jar " + + "-f $(genDir)/extracted/javalib/core-libart.jar " + + "-f $(genDir)/extracted/javalib/okhttp.jar " + + "-f $(genDir)/extracted/javalib/bouncycastle.jar " + + "-f $(genDir)/extracted/javalib/apache-xml.jar && " + + + "$(location merge_zips) $(out) $(out).tmp $(location :art-module-host-exports-for-genrule)", + dist: { + targets: ["droidcore"], + }, +} diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index d2dbaa32e3..6307f921cd 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -700,7 +700,8 @@ static void GenUnsafeGet(HInvoke* invoke, bool is_volatile, CodeGeneratorARM64* codegen) { LocationSummary* locations = invoke->GetLocations(); - DCHECK((type == DataType::Type::kInt32) || + DCHECK((type == DataType::Type::kInt8) || + (type == DataType::Type::kInt32) || (type == DataType::Type::kInt64) || (type == DataType::Type::kReference)); Location base_loc = locations->InAt(1); @@ -791,6 +792,9 @@ void IntrinsicLocationsBuilderARM64::VisitUnsafeGetObject(HInvoke* invoke) { void IntrinsicLocationsBuilderARM64::VisitUnsafeGetObjectVolatile(HInvoke* invoke) { VisitJdkUnsafeGetObjectVolatile(invoke); } +void IntrinsicLocationsBuilderARM64::VisitUnsafeGetByte(HInvoke* invoke) { + VisitJdkUnsafeGetByte(invoke); +} void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeGet(HInvoke* invoke) { CreateIntIntIntToIntLocations(allocator_, invoke); @@ -819,6 +823,9 @@ void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeGetObjectVolatile(HInvoke* in void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeGetObjectAcquire(HInvoke* invoke) { CreateIntIntIntToIntLocations(allocator_, invoke); } +void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeGetByte(HInvoke* invoke) { + CreateIntIntIntToIntLocations(allocator_, invoke); +} void IntrinsicCodeGeneratorARM64::VisitUnsafeGet(HInvoke* invoke) { VisitJdkUnsafeGet(invoke); @@ -838,6 +845,9 @@ void IntrinsicCodeGeneratorARM64::VisitUnsafeGetObject(HInvoke* invoke) { void IntrinsicCodeGeneratorARM64::VisitUnsafeGetObjectVolatile(HInvoke* invoke) { VisitJdkUnsafeGetObjectVolatile(invoke); } +void IntrinsicCodeGeneratorARM64::VisitUnsafeGetByte(HInvoke* invoke) { + VisitJdkUnsafeGetByte(invoke); +} void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeGet(HInvoke* invoke) { GenUnsafeGet(invoke, DataType::Type::kInt32, /*is_volatile=*/ false, codegen_); @@ -866,6 +876,9 @@ void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeGetObjectVolatile(HInvoke* invok void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeGetObjectAcquire(HInvoke* invoke) { GenUnsafeGet(invoke, DataType::Type::kReference, /*is_volatile=*/ true, codegen_); } +void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeGetByte(HInvoke* invoke) { + GenUnsafeGet(invoke, DataType::Type::kInt8, /*is_volatile=*/ false, codegen_); +} static void CreateIntIntIntIntToVoid(ArenaAllocator* allocator, HInvoke* invoke) { LocationSummary* locations = @@ -903,6 +916,9 @@ void IntrinsicLocationsBuilderARM64::VisitUnsafePutLongOrdered(HInvoke* invoke) void IntrinsicLocationsBuilderARM64::VisitUnsafePutLongVolatile(HInvoke* invoke) { VisitJdkUnsafePutLongVolatile(invoke); } +void IntrinsicLocationsBuilderARM64::VisitUnsafePutByte(HInvoke* invoke) { + VisitJdkUnsafePutByte(invoke); +} void IntrinsicLocationsBuilderARM64::VisitJdkUnsafePut(HInvoke* invoke) { CreateIntIntIntIntToVoid(allocator_, invoke); @@ -940,6 +956,9 @@ void IntrinsicLocationsBuilderARM64::VisitJdkUnsafePutLongVolatile(HInvoke* invo void IntrinsicLocationsBuilderARM64::VisitJdkUnsafePutLongRelease(HInvoke* invoke) { CreateIntIntIntIntToVoid(allocator_, invoke); } +void IntrinsicLocationsBuilderARM64::VisitJdkUnsafePutByte(HInvoke* invoke) { + CreateIntIntIntIntToVoid(allocator_, invoke); +} static void GenUnsafePut(HInvoke* invoke, DataType::Type type, @@ -1008,6 +1027,9 @@ void IntrinsicCodeGeneratorARM64::VisitUnsafePutLongOrdered(HInvoke* invoke) { void IntrinsicCodeGeneratorARM64::VisitUnsafePutLongVolatile(HInvoke* invoke) { VisitJdkUnsafePutLongVolatile(invoke); } +void IntrinsicCodeGeneratorARM64::VisitUnsafePutByte(HInvoke* invoke) { + VisitJdkUnsafePutByte(invoke); +} void IntrinsicCodeGeneratorARM64::VisitJdkUnsafePut(HInvoke* invoke) { GenUnsafePut(invoke, @@ -1093,6 +1115,13 @@ void IntrinsicCodeGeneratorARM64::VisitJdkUnsafePutLongRelease(HInvoke* invoke) /*is_ordered=*/ false, codegen_); } +void IntrinsicCodeGeneratorARM64::VisitJdkUnsafePutByte(HInvoke* invoke) { + GenUnsafePut(invoke, + DataType::Type::kInt8, + /*is_volatile=*/ false, + /*is_ordered=*/ false, + codegen_); +} static void CreateUnsafeCASLocations(ArenaAllocator* allocator, HInvoke* invoke) { const bool can_call = gUseReadBarrier && IsUnsafeCASObject(invoke); diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc index 266b5bc799..22c51c69eb 100644 --- a/compiler/optimizing/intrinsics_arm_vixl.cc +++ b/compiler/optimizing/intrinsics_arm_vixl.cc @@ -2902,6 +2902,14 @@ void IntrinsicCodeGeneratorARMVIXL::VisitUnsafeGetObjectVolatile(HInvoke* invoke VisitJdkUnsafeGetObjectVolatile(invoke); } +void IntrinsicLocationsBuilderARMVIXL::VisitUnsafeGetByte(HInvoke* invoke) { + VisitJdkUnsafeGetByte(invoke); +} + +void IntrinsicCodeGeneratorARMVIXL::VisitUnsafeGetByte(HInvoke* invoke) { + VisitJdkUnsafeGetByte(invoke); +} + void IntrinsicLocationsBuilderARMVIXL::VisitJdkUnsafeGet(HInvoke* invoke) { CreateUnsafeGetLocations(invoke, codegen_, DataType::Type::kInt32, /*atomic=*/ false); } @@ -2983,6 +2991,15 @@ void IntrinsicCodeGeneratorARMVIXL::VisitJdkUnsafeGetObjectAcquire(HInvoke* invo invoke, codegen_, DataType::Type::kReference, std::memory_order_acquire, /*atomic=*/ true); } +void IntrinsicLocationsBuilderARMVIXL::VisitJdkUnsafeGetByte(HInvoke* invoke) { + CreateUnsafeGetLocations(invoke, codegen_, DataType::Type::kInt8, /*atomic=*/ false); +} + +void IntrinsicCodeGeneratorARMVIXL::VisitJdkUnsafeGetByte(HInvoke* invoke) { + GenUnsafeGet( + invoke, codegen_, DataType::Type::kInt8, std::memory_order_relaxed, /*atomic=*/ false); +} + static void GenerateIntrinsicSet(CodeGeneratorARMVIXL* codegen, DataType::Type type, std::memory_order order, @@ -3203,6 +3220,14 @@ void IntrinsicCodeGeneratorARMVIXL::VisitUnsafePutLongVolatile(HInvoke* invoke) VisitJdkUnsafePutLongVolatile(invoke); } +void IntrinsicLocationsBuilderARMVIXL::VisitUnsafePutByte(HInvoke* invoke) { + VisitJdkUnsafePutByte(invoke); +} + +void IntrinsicCodeGeneratorARMVIXL::VisitUnsafePutByte(HInvoke* invoke) { + VisitJdkUnsafePutByte(invoke); +} + void IntrinsicLocationsBuilderARMVIXL::VisitJdkUnsafePut(HInvoke* invoke) { CreateUnsafePutLocations(invoke, codegen_, DataType::Type::kInt32, /*atomic=*/ false); } @@ -3215,6 +3240,18 @@ void IntrinsicCodeGeneratorARMVIXL::VisitJdkUnsafePut(HInvoke* invoke) { codegen_); } +void IntrinsicLocationsBuilderARMVIXL::VisitJdkUnsafePutByte(HInvoke* invoke) { + CreateUnsafePutLocations(invoke, codegen_, DataType::Type::kInt8, /*atomic=*/ false); +} + +void IntrinsicCodeGeneratorARMVIXL::VisitJdkUnsafePutByte(HInvoke* invoke) { + GenUnsafePut(invoke, + DataType::Type::kInt8, + std::memory_order_relaxed, + /*atomic=*/ false, + codegen_); +} + void IntrinsicLocationsBuilderARMVIXL::VisitJdkUnsafePutOrdered(HInvoke* invoke) { CreateUnsafePutLocations(invoke, codegen_, DataType::Type::kInt32, /*atomic=*/ true); } diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc index d2072201f8..345e9c6627 100644 --- a/compiler/optimizing/intrinsics_x86.cc +++ b/compiler/optimizing/intrinsics_x86.cc @@ -1691,6 +1691,12 @@ static void GenUnsafeGet(HInvoke* invoke, Location output_loc = locations->Out(); switch (type) { + case DataType::Type::kInt8: { + Register output = output_loc.AsRegister<Register>(); + __ movsxb(output, Address(base, offset, ScaleFactor::TIMES_1, 0)); + break; + } + case DataType::Type::kInt32: { Register output = output_loc.AsRegister<Register>(); __ movl(output, Address(base, offset, ScaleFactor::TIMES_1, 0)); @@ -1802,7 +1808,9 @@ void IntrinsicLocationsBuilderX86::VisitUnsafeGetObject(HInvoke* invoke) { void IntrinsicLocationsBuilderX86::VisitUnsafeGetObjectVolatile(HInvoke* invoke) { VisitJdkUnsafeGetObjectVolatile(invoke); } - +void IntrinsicLocationsBuilderX86::VisitUnsafeGetByte(HInvoke* invoke) { + VisitJdkUnsafeGetByte(invoke); +} void IntrinsicCodeGeneratorX86::VisitUnsafeGet(HInvoke* invoke) { VisitJdkUnsafeGet(invoke); @@ -1822,7 +1830,9 @@ void IntrinsicCodeGeneratorX86::VisitUnsafeGetObject(HInvoke* invoke) { void IntrinsicCodeGeneratorX86::VisitUnsafeGetObjectVolatile(HInvoke* invoke) { VisitJdkUnsafeGetObjectVolatile(invoke); } - +void IntrinsicCodeGeneratorX86::VisitUnsafeGetByte(HInvoke* invoke) { + VisitJdkUnsafeGetByte(invoke); +} void IntrinsicLocationsBuilderX86::VisitJdkUnsafeGet(HInvoke* invoke) { CreateIntIntIntToIntLocations( @@ -1856,6 +1866,10 @@ void IntrinsicLocationsBuilderX86::VisitJdkUnsafeGetObjectAcquire(HInvoke* invok CreateIntIntIntToIntLocations( allocator_, invoke, DataType::Type::kReference, /*is_volatile=*/ true); } +void IntrinsicLocationsBuilderX86::VisitJdkUnsafeGetByte(HInvoke* invoke) { + CreateIntIntIntToIntLocations( + allocator_, invoke, DataType::Type::kInt8, /*is_volatile=*/ false); +} void IntrinsicCodeGeneratorX86::VisitJdkUnsafeGet(HInvoke* invoke) { GenUnsafeGet(invoke, DataType::Type::kInt32, /*is_volatile=*/ false, codegen_); @@ -1884,6 +1898,9 @@ void IntrinsicCodeGeneratorX86::VisitJdkUnsafeGetObjectVolatile(HInvoke* invoke) void IntrinsicCodeGeneratorX86::VisitJdkUnsafeGetObjectAcquire(HInvoke* invoke) { GenUnsafeGet(invoke, DataType::Type::kReference, /*is_volatile=*/ true, codegen_); } +void IntrinsicCodeGeneratorX86::VisitJdkUnsafeGetByte(HInvoke* invoke) { + GenUnsafeGet(invoke, DataType::Type::kInt8, /*is_volatile=*/ false, codegen_); +} static void CreateIntIntIntIntToVoidPlusTempsLocations(ArenaAllocator* allocator, DataType::Type type, @@ -1933,6 +1950,9 @@ void IntrinsicLocationsBuilderX86::VisitUnsafePutLongOrdered(HInvoke* invoke) { void IntrinsicLocationsBuilderX86::VisitUnsafePutLongVolatile(HInvoke* invoke) { VisitJdkUnsafePutLongVolatile(invoke); } +void IntrinsicLocationsBuilderX86::VisitUnsafePutByte(HInvoke* invoke) { + VisitJdkUnsafePutByte(invoke); +} void IntrinsicLocationsBuilderX86::VisitJdkUnsafePut(HInvoke* invoke) { CreateIntIntIntIntToVoidPlusTempsLocations( @@ -1982,6 +2002,10 @@ void IntrinsicLocationsBuilderX86::VisitJdkUnsafePutLongRelease(HInvoke* invoke) CreateIntIntIntIntToVoidPlusTempsLocations( allocator_, DataType::Type::kInt64, invoke, /*is_volatile=*/ true); } +void IntrinsicLocationsBuilderX86::VisitJdkUnsafePutByte(HInvoke* invoke) { + CreateIntIntIntIntToVoidPlusTempsLocations( + allocator_, DataType::Type::kInt8, invoke, /*is_volatile=*/ false); +} // We don't care for ordered: it requires an AnyStore barrier, which is already given by the x86 // memory model. @@ -2058,6 +2082,9 @@ void IntrinsicCodeGeneratorX86::VisitUnsafePutLongOrdered(HInvoke* invoke) { void IntrinsicCodeGeneratorX86::VisitUnsafePutLongVolatile(HInvoke* invoke) { VisitJdkUnsafePutLongVolatile(invoke); } +void IntrinsicCodeGeneratorX86::VisitUnsafePutByte(HInvoke* invoke) { + VisitJdkUnsafePutByte(invoke); +} void IntrinsicCodeGeneratorX86::VisitJdkUnsafePut(HInvoke* invoke) { GenUnsafePut(invoke->GetLocations(), DataType::Type::kInt32, /*is_volatile=*/ false, codegen_); @@ -2099,6 +2126,9 @@ void IntrinsicCodeGeneratorX86::VisitJdkUnsafePutLongVolatile(HInvoke* invoke) { void IntrinsicCodeGeneratorX86::VisitJdkUnsafePutLongRelease(HInvoke* invoke) { GenUnsafePut(invoke->GetLocations(), DataType::Type::kInt64, /*is_volatile=*/ true, codegen_); } +void IntrinsicCodeGeneratorX86::VisitJdkUnsafePutByte(HInvoke* invoke) { + GenUnsafePut(invoke->GetLocations(), DataType::Type::kInt8, /*is_volatile=*/ false, codegen_); +} static void CreateIntIntIntIntIntToInt(ArenaAllocator* allocator, DataType::Type type, diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc index 9d0d5f155e..56bf5ea87d 100644 --- a/compiler/optimizing/intrinsics_x86_64.cc +++ b/compiler/optimizing/intrinsics_x86_64.cc @@ -1883,6 +1883,10 @@ static void GenUnsafeGet(HInvoke* invoke, CpuRegister output = output_loc.AsRegister<CpuRegister>(); switch (type) { + case DataType::Type::kInt8: + __ movsxb(output, Address(base, offset, ScaleFactor::TIMES_1, 0)); + break; + case DataType::Type::kInt32: __ movl(output, Address(base, offset, ScaleFactor::TIMES_1, 0)); break; @@ -1965,6 +1969,9 @@ void IntrinsicLocationsBuilderX86_64::VisitUnsafeGetObject(HInvoke* invoke) { void IntrinsicLocationsBuilderX86_64::VisitUnsafeGetObjectVolatile(HInvoke* invoke) { VisitJdkUnsafeGetObjectVolatile(invoke); } +void IntrinsicLocationsBuilderX86_64::VisitUnsafeGetByte(HInvoke* invoke) { + VisitJdkUnsafeGetByte(invoke); +} void IntrinsicLocationsBuilderX86_64::VisitJdkUnsafeGet(HInvoke* invoke) { CreateIntIntIntToIntLocations(allocator_, invoke); @@ -1993,7 +2000,9 @@ void IntrinsicLocationsBuilderX86_64::VisitJdkUnsafeGetObjectVolatile(HInvoke* i void IntrinsicLocationsBuilderX86_64::VisitJdkUnsafeGetObjectAcquire(HInvoke* invoke) { CreateIntIntIntToIntLocations(allocator_, invoke); } - +void IntrinsicLocationsBuilderX86_64::VisitJdkUnsafeGetByte(HInvoke* invoke) { + CreateIntIntIntToIntLocations(allocator_, invoke); +} void IntrinsicCodeGeneratorX86_64::VisitUnsafeGet(HInvoke* invoke) { VisitJdkUnsafeGet(invoke); @@ -2013,6 +2022,9 @@ void IntrinsicCodeGeneratorX86_64::VisitUnsafeGetObject(HInvoke* invoke) { void IntrinsicCodeGeneratorX86_64::VisitUnsafeGetObjectVolatile(HInvoke* invoke) { VisitJdkUnsafeGetObjectVolatile(invoke); } +void IntrinsicCodeGeneratorX86_64::VisitUnsafeGetByte(HInvoke* invoke) { + VisitJdkUnsafeGetByte(invoke); +} void IntrinsicCodeGeneratorX86_64::VisitJdkUnsafeGet(HInvoke* invoke) { GenUnsafeGet(invoke, DataType::Type::kInt32, /*is_volatile=*/ false, codegen_); @@ -2041,7 +2053,9 @@ void IntrinsicCodeGeneratorX86_64::VisitJdkUnsafeGetObjectVolatile(HInvoke* invo void IntrinsicCodeGeneratorX86_64::VisitJdkUnsafeGetObjectAcquire(HInvoke* invoke) { GenUnsafeGet(invoke, DataType::Type::kReference, /*is_volatile=*/ true, codegen_); } - +void IntrinsicCodeGeneratorX86_64::VisitJdkUnsafeGetByte(HInvoke* invoke) { + GenUnsafeGet(invoke, DataType::Type::kInt8, /*is_volatile=*/false, codegen_); +} static void CreateIntIntIntIntToVoidPlusTempsLocations(ArenaAllocator* allocator, DataType::Type type, @@ -2086,6 +2100,9 @@ void IntrinsicLocationsBuilderX86_64::VisitUnsafePutLongOrdered(HInvoke* invoke) void IntrinsicLocationsBuilderX86_64::VisitUnsafePutLongVolatile(HInvoke* invoke) { VisitJdkUnsafePutLongVolatile(invoke); } +void IntrinsicLocationsBuilderX86_64::VisitUnsafePutByte(HInvoke* invoke) { + VisitJdkUnsafePut(invoke); +} void IntrinsicLocationsBuilderX86_64::VisitJdkUnsafePut(HInvoke* invoke) { CreateIntIntIntIntToVoidPlusTempsLocations(allocator_, DataType::Type::kInt32, invoke); @@ -2123,6 +2140,9 @@ void IntrinsicLocationsBuilderX86_64::VisitJdkUnsafePutLongVolatile(HInvoke* inv void IntrinsicLocationsBuilderX86_64::VisitJdkUnsafePutLongRelease(HInvoke* invoke) { CreateIntIntIntIntToVoidPlusTempsLocations(allocator_, DataType::Type::kInt64, invoke); } +void IntrinsicLocationsBuilderX86_64::VisitJdkUnsafePutByte(HInvoke* invoke) { + CreateIntIntIntIntToVoidPlusTempsLocations(allocator_, DataType::Type::kUint8, invoke); +} // We don't care for ordered: it requires an AnyStore barrier, which is already given by the x86 // memory model. @@ -2185,6 +2205,9 @@ void IntrinsicCodeGeneratorX86_64::VisitUnsafePutLongOrdered(HInvoke* invoke) { void IntrinsicCodeGeneratorX86_64::VisitUnsafePutLongVolatile(HInvoke* invoke) { VisitJdkUnsafePutLongVolatile(invoke); } +void IntrinsicCodeGeneratorX86_64::VisitUnsafePutByte(HInvoke* invoke) { + VisitJdkUnsafePutByte(invoke); +} void IntrinsicCodeGeneratorX86_64::VisitJdkUnsafePut(HInvoke* invoke) { GenUnsafePut(invoke->GetLocations(), DataType::Type::kInt32, /*is_volatile=*/ false, codegen_); @@ -2226,6 +2249,9 @@ void IntrinsicCodeGeneratorX86_64::VisitJdkUnsafePutLongVolatile(HInvoke* invoke void IntrinsicCodeGeneratorX86_64::VisitJdkUnsafePutLongRelease(HInvoke* invoke) { GenUnsafePut(invoke->GetLocations(), DataType::Type::kInt64, /*is_volatile=*/ true, codegen_); } +void IntrinsicCodeGeneratorX86_64::VisitJdkUnsafePutByte(HInvoke* invoke) { + GenUnsafePut(invoke->GetLocations(), DataType::Type::kInt8, /*is_volatile=*/false, codegen_); +} static void CreateUnsafeCASLocations(ArenaAllocator* allocator, DataType::Type type, diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc index df7835d87e..969b8c07c7 100644 --- a/dex2oat/driver/compiler_driver.cc +++ b/dex2oat/driver/compiler_driver.cc @@ -2792,7 +2792,7 @@ std::string CompilerDriver::GetMemoryUsageString(bool extended) const { const size_t java_alloc = heap->GetBytesAllocated(); oss << "arena alloc=" << PrettySize(max_arena_alloc_) << " (" << max_arena_alloc_ << "B)"; oss << " java alloc=" << PrettySize(java_alloc) << " (" << java_alloc << "B)"; -#if defined(__BIONIC__) || defined(__GLIBC__) +#if defined(__BIONIC__) || defined(__GLIBC__) || defined(ANDROID_HOST_MUSL) const struct mallinfo info = mallinfo(); const size_t allocated_space = static_cast<size_t>(info.uordblks); const size_t free_space = static_cast<size_t>(info.fordblks); diff --git a/libartservice/service/java/com/android/server/art/ArtJni.java b/libartservice/service/java/com/android/server/art/ArtJni.java index 2cc9ea8911..f2868eb0d2 100644 --- a/libartservice/service/java/com/android/server/art/ArtJni.java +++ b/libartservice/service/java/com/android/server/art/ArtJni.java @@ -56,8 +56,17 @@ public class ArtJni { return validateClassLoaderContextNative(dexPath, classLoaderContext); } + /** + * Returns the name of the Garbage Collector currently in use in the Android Runtime. + */ + @NonNull + public static String getGarbageCollector() { + return getGarbageCollectorNative(); + } + @Nullable private static native String validateDexPathNative(@NonNull String dexPath); @Nullable private static native String validateClassLoaderContextNative( @NonNull String dexPath, @NonNull String classLoaderContext); + @NonNull private static native String getGarbageCollectorNative(); } diff --git a/libartservice/service/java/com/android/server/art/DumpHelper.java b/libartservice/service/java/com/android/server/art/DumpHelper.java index 2a640ec48d..70d7f8ce0f 100644 --- a/libartservice/service/java/com/android/server/art/DumpHelper.java +++ b/libartservice/service/java/com/android/server/art/DumpHelper.java @@ -75,6 +75,7 @@ public class DumpHelper { .stream() .sorted(Comparator.comparing(PackageState::getPackageName)) .forEach(pkgState -> dumpPackage(pw, snapshot, pkgState)); + pw.printf("\nCurrent GC: %s\n", ArtJni.getGarbageCollector()); } /** diff --git a/libartservice/service/javatests/com/android/server/art/DumpHelperTest.java b/libartservice/service/javatests/com/android/server/art/DumpHelperTest.java index 3833249cb9..5dbe2137a9 100644 --- a/libartservice/service/javatests/com/android/server/art/DumpHelperTest.java +++ b/libartservice/service/javatests/com/android/server/art/DumpHelperTest.java @@ -62,7 +62,7 @@ public class DumpHelperTest { @Rule public StaticMockitoRule mockitoRule = - new StaticMockitoRule(SystemProperties.class, Constants.class); + new StaticMockitoRule(SystemProperties.class, Constants.class, ArtJni.class); @Mock private DumpHelper.Injector mInjector; @Mock private ArtManagerLocal mArtManagerLocal; @@ -83,6 +83,8 @@ public class DumpHelperTest { .when(SystemProperties.get(argThat(arg -> arg.startsWith("ro.dalvik.vm.isa.")))) .thenReturn(""); + lenient().when(ArtJni.getGarbageCollector()).thenReturn("CollectorTypeCMC"); + lenient().when(mInjector.getArtManagerLocal()).thenReturn(mArtManagerLocal); lenient().when(mInjector.getDexUseManager()).thenReturn(mDexUseManagerLocal); lenient().when(mInjector.getArtd()).thenReturn(mArtd); @@ -132,7 +134,9 @@ public class DumpHelperTest { + " arm: [status=verify] [reason=install] [primary-abi]\n" + " [location is /data/app/bar/oat/arm/base.odex]\n" + " arm64: [status=verify] [reason=install]\n" - + " [location is /data/app/bar/oat/arm64/base.odex]\n"; + + " [location is /data/app/bar/oat/arm64/base.odex]\n" + + "\n" + + "Current GC: CollectorTypeCMC\n"; var stringWriter = new StringWriter(); mDumpHelper.dump(new PrintWriter(stringWriter), mSnapshot); diff --git a/libartservice/service/native/service.cc b/libartservice/service/native/service.cc index 7d223e5c35..5901efd9f6 100644 --- a/libartservice/service/native/service.cc +++ b/libartservice/service/native/service.cc @@ -24,7 +24,9 @@ #include "android-base/file.h" #include "android-base/result.h" #include "class_loader_context.h" +#include "gc/heap.h" #include "nativehelper/utils.h" +#include "runtime.h" namespace art { namespace service { @@ -76,6 +78,10 @@ Result<void> ValidateDexPath(const std::string& dex_path) { return {}; } +std::string GetGarbageCollector() { + return Runtime::Current()->GetHeap()->GetForegroundCollectorName(); +} + extern "C" JNIEXPORT jstring JNICALL Java_com_android_server_art_ArtJni_validateDexPathNative(JNIEnv* env, jobject, jstring j_dex_path) { std::string dex_path(GET_UTF_OR_RETURN(env, j_dex_path)); @@ -116,5 +122,10 @@ Java_com_android_server_art_ArtJni_validateClassLoaderContextNative( return nullptr; } +extern "C" JNIEXPORT jstring JNICALL +Java_com_android_server_art_ArtJni_getGarbageCollectorNative(JNIEnv* env, jobject) { + return CREATE_UTF_OR_RETURN(env, GetGarbageCollector()).release(); +} + } // namespace service } // namespace art diff --git a/libartservice/service/native/service.h b/libartservice/service/native/service.h index 7f43f17f0b..85c7dcd39f 100644 --- a/libartservice/service/native/service.h +++ b/libartservice/service/native/service.h @@ -34,6 +34,8 @@ android::base::Result<void> ValidatePathElement(const std::string& path_element, android::base::Result<void> ValidateDexPath(const std::string& dex_path); +std::string GetGarbageCollector(); + } // namespace service } // namespace art diff --git a/libartservice/service/native/service_test.cc b/libartservice/service/native/service_test.cc index 8300bf5e76..d1d429edd7 100644 --- a/libartservice/service/native/service_test.cc +++ b/libartservice/service/native/service_test.cc @@ -17,6 +17,7 @@ #include "service.h" #include "android-base/result-gmock.h" +#include "common_runtime_test.h" #include "gtest/gtest.h" namespace art { @@ -106,6 +107,12 @@ TEST_F(ArtServiceTest, ValidateDexPathNul) { HasError(WithMessage("Path '/a/\0/b.apk' has invalid character '\\0'"s))); } +class ArtServiceGcTest : public CommonRuntimeTest {}; + +TEST_F(ArtServiceGcTest, GetGarbageCollector) { + EXPECT_THAT(GetGarbageCollector(), testing::HasSubstr("CollectorType")); +} + } // namespace } // namespace service } // namespace art diff --git a/libdexfile/dex/dex_file-inl.h b/libdexfile/dex/dex_file-inl.h index d9c5211cc8..cc2f641a38 100644 --- a/libdexfile/dex/dex_file-inl.h +++ b/libdexfile/dex/dex_file-inl.h @@ -319,7 +319,14 @@ bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream, // Emit what was previously there, if anything if (local_in_reg[reg].is_live_) { local_in_reg[reg].end_address_ = address; - new_local_callback(local_in_reg[reg]); + // Parameters with generic types cannot be encoded in the debug_info_item header. So d8 + // encodes it as null in the header with start and end address as 0. There will be a + // START_LOCAL_EXTENDED that will declare the parameter with correct signature + // Debuggers get confused when they see empty ranges. So don't emit them. + // See b/297843934 for more details. + if (local_in_reg[reg].end_address_ != 0) { + new_local_callback(local_in_reg[reg]); + } } local_in_reg[reg].name_ = index_to_string_data(name_idx); diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 2d1d393000..ab82f14c53 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -16,20 +16,18 @@ #include "heap.h" +#include <sys/types.h> +#include <unistd.h> + #include <limits> -#include "android-base/thread_annotations.h" -#if defined(__BIONIC__) || defined(__GLIBC__) -#include <malloc.h> // For mallinfo() -#endif #include <memory> #include <random> -#include <unistd.h> -#include <sys/types.h> +#include <sstream> #include <vector> -#include "android-base/stringprintf.h" - #include "allocation_listener.h" +#include "android-base/stringprintf.h" +#include "android-base/thread_annotations.h" #include "art_field-inl.h" #include "backtrace_helper.h" #include "base/allocator.h" @@ -108,6 +106,10 @@ #include "verify_object-inl.h" #include "well_known_classes.h" +#if defined(__BIONIC__) || defined(__GLIBC__) || defined(ANDROID_HOST_MUSL) +#include <malloc.h> // For mallinfo() +#endif + namespace art { #ifdef ART_TARGET_ANDROID @@ -2655,7 +2657,7 @@ void Heap::TraceHeapSize(size_t heap_size) { size_t Heap::GetNativeBytes() { size_t malloc_bytes; -#if defined(__BIONIC__) || defined(__GLIBC__) +#if defined(__BIONIC__) || defined(__GLIBC__) || defined(ANDROID_HOST_MUSL) IF_GLIBC(size_t mmapped_bytes;) struct mallinfo mi = mallinfo(); // In spite of the documentation, the jemalloc version of this call seems to do what we want, @@ -4758,5 +4760,11 @@ bool Heap::AddHeapTask(gc::HeapTask* task) { return true; } +std::string Heap::GetForegroundCollectorName() { + std::ostringstream oss; + oss << foreground_collector_type_; + return oss.str(); +} + } // namespace gc } // namespace art diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index d7f6948b85..489be370ee 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -843,6 +843,7 @@ class Heap { bool IsMovingGc() const { return IsMovingGc(CurrentCollectorType()); } CollectorType GetForegroundCollectorType() const { return foreground_collector_type_; } + std::string GetForegroundCollectorName(); bool IsGcConcurrentAndMoving() const { if (IsGcConcurrent() && IsMovingGc(collector_type_)) { diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h index 281c1f3cb3..531448b313 100644 --- a/runtime/hidden_api.h +++ b/runtime/hidden_api.h @@ -358,9 +358,11 @@ ALWAYS_INLINE inline uint32_t GetRuntimeFlags(ArtMethod* method) case Intrinsics::kJdkUnsafeGet: case Intrinsics::kJdkUnsafeGetLong: case Intrinsics::kJdkUnsafeGetObject: + case Intrinsics::kJdkUnsafeGetByte: case Intrinsics::kJdkUnsafePutLong: case Intrinsics::kJdkUnsafePut: case Intrinsics::kJdkUnsafePutObject: + case Intrinsics::kJdkUnsafePutByte: return 0u; case Intrinsics::kFP16Ceil: case Intrinsics::kFP16Compare: @@ -376,10 +378,12 @@ ALWAYS_INLINE inline uint32_t GetRuntimeFlags(ArtMethod* method) case Intrinsics::kFP16Rint: case Intrinsics::kUnsafeGet: case Intrinsics::kUnsafeGetLong: + case Intrinsics::kUnsafeGetByte: case Intrinsics::kUnsafeGetObject: case Intrinsics::kUnsafePutLong: case Intrinsics::kUnsafePut: case Intrinsics::kUnsafePutObject: + case Intrinsics::kUnsafePutByte: return kAccCorePlatformApi; default: // Remaining intrinsics are public API. We DCHECK that in SetIntrinsic(). diff --git a/runtime/image.cc b/runtime/image.cc index 37437b4b86..fda755353d 100644 --- a/runtime/image.cc +++ b/runtime/image.cc @@ -257,48 +257,36 @@ const char* ImageHeader::GetImageSectionName(ImageSections index) { } } -// If `image_storage_mode` is compressed, compress data from `source` -// into `storage`, and return an array pointing to the compressed. -// If the mode is uncompressed, just return an array pointing to `source`. -static ArrayRef<const uint8_t> MaybeCompressData(ArrayRef<const uint8_t> source, - ImageHeader::StorageMode image_storage_mode, - /*out*/ dchecked_vector<uint8_t>* storage) { +// Compress data from `source` into `storage`. +static bool CompressData(ArrayRef<const uint8_t> source, + ImageHeader::StorageMode image_storage_mode, + /*out*/ dchecked_vector<uint8_t>* storage) { const uint64_t compress_start_time = NanoTime(); - switch (image_storage_mode) { - case ImageHeader::kStorageModeLZ4: { - storage->resize(LZ4_compressBound(source.size())); - size_t data_size = LZ4_compress_default( - reinterpret_cast<char*>(const_cast<uint8_t*>(source.data())), - reinterpret_cast<char*>(storage->data()), - source.size(), - storage->size()); - storage->resize(data_size); - break; - } - case ImageHeader::kStorageModeLZ4HC: { - // Bound is same as non HC. - storage->resize(LZ4_compressBound(source.size())); - size_t data_size = LZ4_compress_HC( - reinterpret_cast<const char*>(const_cast<uint8_t*>(source.data())), - reinterpret_cast<char*>(storage->data()), - source.size(), - storage->size(), - LZ4HC_CLEVEL_MAX); - storage->resize(data_size); - break; - } - case ImageHeader::kStorageModeUncompressed: { - return source; - } - default: { - LOG(FATAL) << "Unsupported"; - UNREACHABLE(); - } + // Bound is same for both LZ4 and LZ4HC. + storage->resize(LZ4_compressBound(source.size())); + size_t data_size = 0; + if (image_storage_mode == ImageHeader::kStorageModeLZ4) { + data_size = LZ4_compress_default( + reinterpret_cast<char*>(const_cast<uint8_t*>(source.data())), + reinterpret_cast<char*>(storage->data()), + source.size(), + storage->size()); + } else { + DCHECK_EQ(image_storage_mode, ImageHeader::kStorageModeLZ4HC); + data_size = LZ4_compress_HC( + reinterpret_cast<const char*>(const_cast<uint8_t*>(source.data())), + reinterpret_cast<char*>(storage->data()), + source.size(), + storage->size(), + LZ4HC_CLEVEL_MAX); + } + + if (data_size == 0) { + return false; } + storage->resize(data_size); - DCHECK(image_storage_mode == ImageHeader::kStorageModeLZ4 || - image_storage_mode == ImageHeader::kStorageModeLZ4HC); VLOG(image) << "Compressed from " << source.size() << " to " << storage->size() << " in " << PrettyDuration(NanoTime() - compress_start_time); if (kIsDebugBuild) { @@ -319,7 +307,7 @@ static ArrayRef<const uint8_t> MaybeCompressData(ArrayRef<const uint8_t> source, CHECK_EQ(decompressed_size, decompressed.size()); CHECK_EQ(memcmp(source.data(), decompressed.data(), source.size()), 0) << image_storage_mode; } - return ArrayRef<const uint8_t>(*storage); + return true; } bool ImageHeader::WriteData(const ImageFileGuard& image_file, @@ -360,10 +348,16 @@ bool ImageHeader::WriteData(const ImageFileGuard& image_file, for (const std::pair<uint32_t, uint32_t> block : block_sources) { ArrayRef<const uint8_t> raw_image_data(data + block.first, block.second); dchecked_vector<uint8_t> compressed_data; - ArrayRef<const uint8_t> image_data = - MaybeCompressData(raw_image_data, image_storage_mode, &compressed_data); - - if (!is_compressed) { + ArrayRef<const uint8_t> image_data; + if (is_compressed) { + if (!CompressData(raw_image_data, image_storage_mode, &compressed_data)) { + *error_msg = "Error compressing data for " + + image_file->GetPath() + ": " + std::string(strerror(errno)); + return false; + } + image_data = ArrayRef<const uint8_t>(compressed_data); + } else { + image_data = raw_image_data; // For uncompressed, preserve alignment since the image will be directly mapped. out_offset = block.first; } diff --git a/runtime/intrinsics_list.h b/runtime/intrinsics_list.h index 256cd2e5fe..c4b687efe2 100644 --- a/runtime/intrinsics_list.h +++ b/runtime/intrinsics_list.h @@ -221,6 +221,7 @@ V(UnsafeGetObjectVolatile, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;") \ V(UnsafeGetLong, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getLong", "(Ljava/lang/Object;J)J") \ V(UnsafeGetLongVolatile, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getLongVolatile", "(Ljava/lang/Object;J)J") \ + V(UnsafeGetByte, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getByte", "(Ljava/lang/Object;J)B") \ V(UnsafePut, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putInt", "(Ljava/lang/Object;JI)V") \ V(UnsafePutOrdered, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putOrderedInt", "(Ljava/lang/Object;JI)V") \ V(UnsafePutVolatile, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putIntVolatile", "(Ljava/lang/Object;JI)V") \ @@ -230,6 +231,7 @@ V(UnsafePutLong, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putLong", "(Ljava/lang/Object;JJ)V") \ V(UnsafePutLongOrdered, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putOrderedLong", "(Ljava/lang/Object;JJ)V") \ V(UnsafePutLongVolatile, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putLongVolatile", "(Ljava/lang/Object;JJ)V") \ + V(UnsafePutByte, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putByte", "(Ljava/lang/Object;JB)V") \ V(UnsafeGetAndAddInt, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndAddInt", "(Ljava/lang/Object;JI)I") \ V(UnsafeGetAndAddLong, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndAddLong", "(Ljava/lang/Object;JJ)J") \ V(UnsafeGetAndSetInt, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndSetInt", "(Ljava/lang/Object;JI)I") \ @@ -253,6 +255,7 @@ V(JdkUnsafeGetLong, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "getLong", "(Ljava/lang/Object;J)J") \ V(JdkUnsafeGetLongVolatile, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "getLongVolatile", "(Ljava/lang/Object;J)J") \ V(JdkUnsafeGetLongAcquire, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "getLongAcquire", "(Ljava/lang/Object;J)J") \ + V(JdkUnsafeGetByte, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "getByte", "(Ljava/lang/Object;J)B") \ V(JdkUnsafePut, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "putInt", "(Ljava/lang/Object;JI)V") \ V(JdkUnsafePutOrdered, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "putOrderedInt", "(Ljava/lang/Object;JI)V") \ V(JdkUnsafePutRelease, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "putIntRelease", "(Ljava/lang/Object;JI)V") \ @@ -265,6 +268,7 @@ V(JdkUnsafePutLongOrdered, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "putOrderedLong", "(Ljava/lang/Object;JJ)V") \ V(JdkUnsafePutLongVolatile, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "putLongVolatile", "(Ljava/lang/Object;JJ)V") \ V(JdkUnsafePutLongRelease, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "putLongRelease", "(Ljava/lang/Object;JJ)V") \ + V(JdkUnsafePutByte, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "putByte", "(Ljava/lang/Object;JB)V") \ V(JdkUnsafeGetAndAddInt, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "getAndAddInt", "(Ljava/lang/Object;JI)I") \ V(JdkUnsafeGetAndAddLong, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "getAndAddLong", "(Ljava/lang/Object;JJ)J") \ V(JdkUnsafeGetAndSetInt, kVirtual, kNeedsEnvironment, kAllSideEffects, kCanThrow, "Ljdk/internal/misc/Unsafe;", "getAndSetInt", "(Ljava/lang/Object;JI)I") \ diff --git a/test/004-UnsafeTest/src/Main.java b/test/004-UnsafeTest/src/Main.java index 9176e89aaf..cfa36918b3 100644 --- a/test/004-UnsafeTest/src/Main.java +++ b/test/004-UnsafeTest/src/Main.java @@ -136,6 +136,14 @@ public class Main { check(t.objectVar, objectValue, "Unsafe.putObject(Object, long, Object)"); check(unsafe.getObject(t, objectOffset), objectValue, "Unsafe.getObject(Object, long)"); + byte byteValue = 123; + Field byteField = TestClass.class.getDeclaredField("byteVar"); + long byteOffset = unsafe.objectFieldOffset(byteField); + check(unsafe.getByte(t, byteOffset), 0, "Unsafe.getByte(Object, long) - initial"); + unsafe.putByte(t, byteOffset, byteValue); + check(t.byteVar, byteValue, "Unsafe.putByte(Object, long, byte)"); + check(unsafe.getByte(t, byteOffset), byteValue, "Unsafe.getByte(Object, long)"); + if (unsafe.compareAndSwapInt(t, intOffset, 0, 1)) { System.out.println("Unexpectedly succeeding compareAndSwapInt(t, intOffset, 0, 1)"); } @@ -288,6 +296,7 @@ public class Main { public int intVar = 0; public long longVar = 0; public Object objectVar = null; + public byte byteVar = 0; } private static class TestVolatileClass { diff --git a/test/1911-get-local-var-table/src/art/Test1911.java b/test/1911-get-local-var-table/src/art/Test1911.java index 4dd9054bf0..3e2eec21b7 100644 --- a/test/1911-get-local-var-table/src/art/Test1911.java +++ b/test/1911-get-local-var-table/src/art/Test1911.java @@ -18,8 +18,10 @@ package art; import java.lang.reflect.Constructor; import java.lang.reflect.Executable; +import java.lang.Integer; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.ArrayList; import java.util.Base64; import java.util.HashSet; import java.util.Set; @@ -27,8 +29,8 @@ import java.util.Set; public class Test1911 { // Class/dex file containing the following class. // - // CLASS_BYTES generated with java version 1.8.0_45: javac -g art/Target.java - // DEX_BYTES generated with dx version 1.14: dx --dex --output=./classes.dex art/Target.class + // CLASS_BYTES generated with java version 17.0.4.1: javac -g art/Target.java + // DEX_BYTES generated with d8 version 8.3.7-dev: d8 --debug art/Target.class // // package art; // import java.util.ArrayList; @@ -53,58 +55,76 @@ public class Test1911 { // long q = 3 * p; // doNothing(p, q, o, i); // } + // public void testGenericParameters(ArrayList<Integer> array, int i, Integer val) { + // array.set(i, val); + // } // } public static byte[] CLASS_BYTES = Base64.getDecoder().decode( - "yv66vgAAADQARgoABAAuCQANAC8KAA0AMAcAMQY/0zMzMzMzMwoAMgAzCgA0ADUHADYKAAkALgoA" + - "NwA4CgA5ADoHADsBAAN6enoBAAFJAQAGPGluaXQ+AQAEKEkpVgEABENvZGUBAA9MaW5lTnVtYmVy" + - "VGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAMTGFydC9UYXJnZXQ7AQADeHh4AQAB" + - "cQEACWRvTm90aGluZwEAFihbTGphdmEvbGFuZy9PYmplY3Q7KVYBAARvYmpzAQATW0xqYXZhL2xh" + - "bmcvT2JqZWN0OwEAC2RvU29tZXRoaW5nAQABRgEAAWkBAAFEAQABegEAAXgBAAF5AQABbwEAEkxq" + - "YXZhL2xhbmcvT2JqZWN0OwEAFUxqYXZhL3V0aWwvQXJyYXlMaXN0OwEAAXABAAFKAQAWTG9jYWxW" + - "YXJpYWJsZVR5cGVUYWJsZQEAKkxqYXZhL3V0aWwvQXJyYXlMaXN0PExqYXZhL2xhbmcvSW50ZWdl" + - "cjs+OwEADVN0YWNrTWFwVGFibGUBAApTb3VyY2VGaWxlAQALVGFyZ2V0LmphdmEMABAAPAwADgAP" + - "DAAZABoBABBqYXZhL2xhbmcvT2JqZWN0BwA9DAA+AD8HAEAMAD4AQQEAE2phdmEvdXRpbC9BcnJh" + - "eUxpc3QHAEIMAD4AQwcARAwAPgBFAQAKYXJ0L1RhcmdldAEAAygpVgEAD2phdmEvbGFuZy9GbG9h" + - "dAEAB3ZhbHVlT2YBABQoRilMamF2YS9sYW5nL0Zsb2F0OwEAEGphdmEvbGFuZy9Eb3VibGUBABUo" + - "RClMamF2YS9sYW5nL0RvdWJsZTsBABFqYXZhL2xhbmcvSW50ZWdlcgEAFihJKUxqYXZhL2xhbmcv" + - "SW50ZWdlcjsBAA5qYXZhL2xhbmcvTG9uZwEAEyhKKUxqYXZhL2xhbmcvTG9uZzsAIQANAAQAAAAB" + - "AAEADgAPAAAAAwABABAAEQABABIAAABYAAIAAwAAAA4qtwABGwdoPSoctQACsQAAAAIAEwAAABIA" + - "BAAAAAUABAAGAAgABwANAAgAFAAAACAAAwAAAA4AFQAWAAAAAAAOABcADwABAAgABgAYAA8AAgCJ" + - "ABkAGgABABIAAAAvAAEAAQAAAAUquAADsQAAAAIAEwAAAAYAAQAAAAkAFAAAAAwAAQAAAAUAGwAc" + - "AAAAAQAdABEAAQASAAABWAAFAAgAAACCBL0ABFkDKlO4AAMbBmA9Az4dHBtoogAvHB1khjgEFAAF" + - "FwSNazkFBb0ABFkDFwS4AAdTWQQYBbgACFO4AAOEAwGn/9C7AARZtwABTrsACVm3AAo6BAcbgDYF" + - "BhUFaIU3Bge9AARZAxUFuAALU1kEFga4AAxTWQUtU1kGGQRTuAADsQAAAAQAEwAAADYADQAAAAsA" + - "CwAMAA8ADQAYAA4AHgAPACcAEAA+AA0ARAASAEwAEwBVABQAWgAVAGEAFgCBABcAFAAAAGYACgAe" + - "ACAAGAAeAAQAJwAXAB8AIAAFABEAMwAhAA8AAwAAAIIAFQAWAAAAAACCACIADwABAA8AcwAjAA8A" + - "AgBMADYAJAAlAAMAVQAtAB8AJgAEAFoAKAAnAA8ABQBhACEAGAAoAAYAKQAAAAwAAQBVAC0AHwAq" + - "AAQAKwAAAAoAAv0AEQEB+gAyAAEALAAAAAIALQ=="); + "yv66vgAAADcAUQoABAA2CQAOADcKAA4AOAcAOQY/0zMzMzMzMwoAOgA7CgA8AD0HAD4KAAkANgoA" + + "PwBACgBBAEIKAAkAQwcARAEAA3p6egEAAUkBAAY8aW5pdD4BAAQoSSlWAQAEQ29kZQEAD0xpbmVO" + + "dW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAxMYXJ0L1RhcmdldDsBAAN4" + + "eHgBAAFxAQAJZG9Ob3RoaW5nAQAWKFtMamF2YS9sYW5nL09iamVjdDspVgEABG9ianMBABNbTGph" + + "dmEvbGFuZy9PYmplY3Q7AQALZG9Tb21ldGhpbmcBAAFGAQABaQEAAUQBAAF6AQABeAEAAXkBAAFv" + + "AQASTGphdmEvbGFuZy9PYmplY3Q7AQAVTGphdmEvdXRpbC9BcnJheUxpc3Q7AQABcAEAAUoBABZM" + + "b2NhbFZhcmlhYmxlVHlwZVRhYmxlAQAqTGphdmEvdXRpbC9BcnJheUxpc3Q8TGphdmEvbGFuZy9J" + + "bnRlZ2VyOz47AQANU3RhY2tNYXBUYWJsZQEAFXRlc3RHZW5lcmljUGFyYW1ldGVycwEALChMamF2" + + "YS91dGlsL0FycmF5TGlzdDtJTGphdmEvbGFuZy9JbnRlZ2VyOylWAQAFYXJyYXkBAAN2YWwBABNM" + + "amF2YS9sYW5nL0ludGVnZXI7AQAJU2lnbmF0dXJlAQBBKExqYXZhL3V0aWwvQXJyYXlMaXN0PExq" + + "YXZhL2xhbmcvSW50ZWdlcjs+O0lMamF2YS9sYW5nL0ludGVnZXI7KVYBAApTb3VyY2VGaWxlAQAL" + + "VGFyZ2V0LmphdmEMABEARQwADwAQDAAaABsBABBqYXZhL2xhbmcvT2JqZWN0BwBGDABHAEgHAEkM" + + "AEcASgEAE2phdmEvdXRpbC9BcnJheUxpc3QHAEsMAEcATAcATQwARwBODABPAFABAAphcnQvVGFy" + + "Z2V0AQADKClWAQAPamF2YS9sYW5nL0Zsb2F0AQAHdmFsdWVPZgEAFChGKUxqYXZhL2xhbmcvRmxv" + + "YXQ7AQAQamF2YS9sYW5nL0RvdWJsZQEAFShEKUxqYXZhL2xhbmcvRG91YmxlOwEAEWphdmEvbGFu" + + "Zy9JbnRlZ2VyAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwEADmphdmEvbGFuZy9Mb25nAQATKEop" + + "TGphdmEvbGFuZy9Mb25nOwEAA3NldAEAJyhJTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcv" + + "T2JqZWN0OwAhAA4ABAAAAAEAAQAPABAAAAAEAAEAEQASAAEAEwAAAFgAAgADAAAADiq3AAEbB2g9" + + "Khy1AAKxAAAAAgAUAAAAEgAEAAAACAAEAAkACAAKAA0ACwAVAAAAIAADAAAADgAWABcAAAAAAA4A" + + "GAAQAAEACAAGABkAEAACAIkAGgAbAAEAEwAAAC8AAQABAAAABSq4AAOxAAAAAgAUAAAABgABAAAA" + + "DQAVAAAADAABAAAABQAcAB0AAAABAB4AEgABABMAAAFYAAUACAAAAIIEvQAEWQMqU7gAAxsGYD0D" + + "Ph0cG2iiAC8cHWSGOAQUAAUXBI1rOQUFvQAEWQMXBLgAB1NZBBgFuAAIU7gAA4QDAaf/0LsABFm3" + + "AAFOuwAJWbcACjoEBxuANgUGFQVohTcGB70ABFkDFQW4AAtTWQQWBrgADFNZBS1TWQYZBFO4AAOx" + + "AAAABAAUAAAANgANAAAAEAALABEADwASABgAEwAeABQAJwAVAD4AEgBEABcATAAYAFUAGQBaABoA" + + "YQAbAIEAHAAVAAAAZgAKAB4AIAAZAB8ABAAnABcAIAAhAAUAEQAzACIAEAADAAAAggAWABcAAAAA" + + "AIIAIwAQAAEADwBzACQAEAACAEwANgAlACYAAwBVAC0AIAAnAAQAWgAoACgAEAAFAGEAIQAZACkA" + + "BgAqAAAADAABAFUALQAgACsABAAsAAAACgAC/QARAQH6ADIAAQAtAC4AAgATAAAAZgADAAQAAAAI" + + "KxwttgANV7EAAAADABQAAAAKAAIAAAAfAAcAIAAVAAAAKgAEAAAACAAWABcAAAAAAAgALwAnAAEA" + + "AAAIACAAEAACAAAACAAwADEAAwAqAAAADAABAAAACAAvACsAAQAyAAAAAgAzAAEANAAAAAIANQ=="); public static byte[] DEX_BYTES = Base64.getDecoder().decode( - "ZGV4CjAzNQCQtgjEV631Ma/btYyIy2IzqHWNN+nZiwl0BQAAcAAAAHhWNBIAAAAAAAAAANQEAAAk" + - "AAAAcAAAAA0AAAAAAQAABwAAADQBAAABAAAAiAEAAAkAAACQAQAAAQAAANgBAAB8AwAA+AEAAB4D" + - "AAAmAwAAKQMAACwDAAAvAwAAMgMAADYDAAA6AwAAPgMAAEIDAABQAwAAZAMAAHcDAACMAwAAngMA" + - "ALIDAADJAwAA9QMAAAIEAAAFBAAACQQAAA0EAAAiBAAALQQAADoEAAA9BAAAQAQAAEYEAABJBAAA" + - "TAQAAFIEAABbBAAAXgQAAGMEAABmBAAAaQQAAAEAAAACAAAAAwAAAAQAAAAJAAAACgAAAAsAAAAM" + - "AAAADQAAAA4AAAAPAAAAEgAAABUAAAAFAAAABQAAAPgCAAAGAAAABgAAAAADAAAHAAAABwAAAAgD" + - "AAAIAAAACAAAABADAAASAAAACwAAAAAAAAATAAAACwAAAAgDAAAUAAAACwAAABgDAAAEAAIAIwAA" + - "AAQABQAAAAAABAAGABYAAAAEAAUAFwAAAAUAAAAeAAAABgABAB4AAAAHAAIAHgAAAAgAAwAeAAAA" + - "CQAEAAAAAAAKAAQAAAAAAAQAAAABAAAACQAAAAAAAAARAAAAAAAAAL4EAAAAAAAAAwACAAEAAABu" + - "BAAACAAAAHAQBwABANoAAgRZEAAADgABAAEAAQAAAHsEAAAEAAAAcRABAAAADgAQAAIAAgAAAIEE" + - "AABcAAAAEhkjmQwAEgpNDgkKcRABAAkA2AUPAxIIkgkFDzWYJACRCQUIgpYYCjMzMzMzM9M/iWyt" + - "AAoMEikjmQwAEgpxEAQABgAMC00LCQoSGnEgAwAQAAwLTQsJCnEQAQAJANgICAEo2yIDCQBwEAcA" + - "AwAiAgoAcBAIAAIA3gQPBNoJBAOBlhJJI5kMABIKcRAFAAQADAtNCwkKEhpxIAYAdgAMC00LCQoS" + - "Kk0DCQoSOk0CCQpxEAEACQAOAAEAAAAAAAAAAQAAAAEAAAABAAAAAgAAAAEAAAADAAAAAQAAAAwA" + - "Bjxpbml0PgABRAABRgABSQABSgACTEQAAkxGAAJMSQACTEoADExhcnQvVGFyZ2V0OwASTGphdmEv" + - "bGFuZy9Eb3VibGU7ABFMamF2YS9sYW5nL0Zsb2F0OwATTGphdmEvbGFuZy9JbnRlZ2VyOwAQTGph" + - "dmEvbGFuZy9Mb25nOwASTGphdmEvbGFuZy9PYmplY3Q7ABVMamF2YS91dGlsL0FycmF5TGlzdDsA" + - "KkxqYXZhL3V0aWwvQXJyYXlMaXN0PExqYXZhL2xhbmcvSW50ZWdlcjs+OwALVGFyZ2V0LmphdmEA" + - "AVYAAlZJAAJWTAATW0xqYXZhL2xhbmcvT2JqZWN0OwAJZG9Ob3RoaW5nAAtkb1NvbWV0aGluZwAB" + - "aQABbwAEb2JqcwABcAABcQAEdGhpcwAHdmFsdWVPZgABeAADeHh4AAF5AAF6AAN6enoABQEhBw48" + - "LQMAHQMtAAkBGwcOAAsBIAcOli0DBSIDAQEDCCMDSzwDBh0ChwMAGQEBFAtABQAFBloDAxoKWgQC" + - "GQsRLQMEHAM8AwYdBAEaDwAAAQIBAAEAgYAE+AMBiQGYBAIBsAQADQAAAAAAAAABAAAAAAAAAAEA" + - "AAAkAAAAcAAAAAIAAAANAAAAAAEAAAMAAAAHAAAANAEAAAQAAAABAAAAiAEAAAUAAAAJAAAAkAEA" + - "AAYAAAABAAAA2AEAAAEgAAADAAAA+AEAAAEQAAAFAAAA+AIAAAIgAAAkAAAAHgMAAAMgAAADAAAA" + - "bgQAAAAgAAABAAAAvgQAAAAQAAABAAAA1AQAAA=="); - + "ZGV4CjAzNQAALyjG3vy0POIlfGUh9Q7yf3NFwlp6VbWoBwAAcAAAAHhWNBIAAAAAAAAAAOQGAAAz" + + "AAAAcAAAAA8AAAA8AQAACgAAAHgBAAABAAAA8AEAAAwAAAD4AQAAAQAAAFgCAAAwBQAAeAIAACIE" + + "AAAlBAAAKQQAADEEAAA2BAAAOQQAADwEAAA/BAAAQgQAAEYEAABKBAAATgQAAFMEAABXBAAAZQQA" + + "AIQEAACYBAAAqwQAAMAEAADSBAAA5gQAAP0EAAAUBQAAQAUAAE0FAABQBQAAVAUAAFgFAABeBQAA" + + "YQUAAGUFAAB6BQAAgQUAAIwFAACZBQAAnAUAAKMFAACmBQAArAUAAK8FAACyBQAAtwUAAM4FAADT" + + "BQAA2gUAAOMFAADmBQAA6wUAAO4FAADxBQAA9gUAAAQAAAAFAAAABgAAAAcAAAANAAAADgAAAA8A" + + "AAAQAAAAEQAAABIAAAATAAAAFAAAABgAAAAcAAAAHgAAAAgAAAAGAAAA6AMAAAkAAAAHAAAA8AMA" + + "AAoAAAAIAAAA+AMAAAwAAAAJAAAAAAQAAAsAAAAKAAAACAQAABgAAAAMAAAAAAAAABkAAAAMAAAA" + + "+AMAABsAAAAMAAAAEAQAABoAAAAMAAAAHAQAAB0AAAANAAAA6AMAAAQAAgAxAAAABAAGAAIAAAAE" + + "AAgAIAAAAAQABgAhAAAABAAHACkAAAAGAAkAIwAAAAYAAAAsAAAABwABACwAAAAIAAIALAAAAAkA" + + "AwAsAAAACgAFAAIAAAALAAUAAgAAAAsABAAoAAAABAAAAAEAAAAKAAAAAAAAABcAAADMBgAApgYA" + + "AAAAAAADAAIAAQAAAIwDAAAIAAAAcBAJAAEA2gACBFkQAAAOAAEAAQABAAAAmAMAAAQAAABxEAEA" + + "AAAOAA4AAgACAAAAnQMAAFoAAAASECMBDgASAk0MAQJxEAEAAQDYAQ0DEgOSBAENEiU1QyQAkQQB" + + "A4JEGAYzMzMzMzPTP4lIcSAEAJgArQgIBnEQBgAEAAwGcSAFAJgADAcjVQ4ATQYFAk0HBQBxEAEA" + + "BQDYAwMBKNoiAwoAcBAJAAMAIgQLAHAQCgAEAN4GDQTaBwYDgXdxEAcABgAMCXEgCACHAAwKEksj" + + "uw4ATQkLAk0KCwBNAwsFEjBNBAsAcRABAAsADgAEAAQAAwAAANsDAAAEAAAAbjALACEDDgAIAS8O" + + "PC0DACgDLQANASYOABABLg6WLQMBMAMBAQMDMQNaPAMEKAK0AwgjAQERCwUEBQhABQNaAwMlC1oE" + + "BCMMFy0DBicDPAMHKAQBFw8AHwMAIysOBAEgDBc8AAEAAAAAAAAAAQAAAAEAAAABAAAAAgAAAAEA" + + "AAADAAAAAgAAAAIACgADAAAACwACAAgAAAABAAAADgABKAACKVYABjxpbml0PgADPjtJAAFEAAFG" + + "AAFJAAFKAAJMRAACTEYAAkxJAANMSUwAAkxKAAxMYXJ0L1RhcmdldDsAHUxkYWx2aWsvYW5ub3Rh" + + "dGlvbi9TaWduYXR1cmU7ABJMamF2YS9sYW5nL0RvdWJsZTsAEUxqYXZhL2xhbmcvRmxvYXQ7ABNM" + + "amF2YS9sYW5nL0ludGVnZXI7ABBMamF2YS9sYW5nL0xvbmc7ABJMamF2YS9sYW5nL09iamVjdDsA" + + "FUxqYXZhL3V0aWwvQXJyYXlMaXN0OwAVTGphdmEvdXRpbC9BcnJheUxpc3Q8ACpMamF2YS91dGls" + + "L0FycmF5TGlzdDxMamF2YS9sYW5nL0ludGVnZXI7PjsAC1RhcmdldC5qYXZhAAFWAAJWSQACVkwA" + + "BFZMSUwAAVoAAlpEABNbTGphdmEvbGFuZy9PYmplY3Q7AAVhcnJheQAJZG9Ob3RoaW5nAAtkb1Nv" + + "bWV0aGluZwABaQAFaXNOYU4AAW8ABG9ianMAAXAAAXEAA3NldAAVdGVzdEdlbmVyaWNQYXJhbWV0" + + "ZXJzAAN2YWwABXZhbHVlAAd2YWx1ZU9mAAF4AAN4eHgAAXkAAXoAA3p6egCbAX5+RDh7ImJhY2tl" + + "bmQiOiJkZXgiLCJjb21waWxhdGlvbi1tb2RlIjoiZGVidWciLCJoYXMtY2hlY2tzdW1zIjpmYWxz" + + "ZSwibWluLWFwaSI6MSwic2hhLTEiOiIzMTAxYWQ2Zjc0ZWUyMzI1MjhkZmM2NmEyNjE3YTkzODM4" + + "NGU2NmVhIiwidmVyc2lvbiI6IjguMy43LWRldiJ9AAIFASscBhcAFxUXERcDFxEXAQABAgIAAQCB" + + "gAT4BAGJAZgFAgGwBQEB9AYAAAAAAAEAAACUBgAAwAYAAAAAAAABAAAAAAAAAAMAAADEBgAAEAAA" + + "AAAAAAABAAAAAAAAAAEAAAAzAAAAcAAAAAIAAAAPAAAAPAEAAAMAAAAKAAAAeAEAAAQAAAABAAAA" + + "8AEAAAUAAAAMAAAA+AEAAAYAAAABAAAAWAIAAAEgAAAEAAAAeAIAAAMgAAAEAAAAjAMAAAEQAAAH" + + "AAAA6AMAAAIgAAAzAAAAIgQAAAQgAAABAAAAlAYAAAAgAAABAAAApgYAAAMQAAACAAAAwAYAAAYg" + + "AAABAAAAzAYAAAAQAAABAAAA5AYAAA=="); // The variables of the functions in the above Target class. public static Set<Locals.VariableDescription>[] CONSTRUCTOR_VARIABLES = new Set[] { @@ -149,23 +169,49 @@ public class Test1911 { 4))), // ART Local variable table new HashSet<>(Arrays.asList( - new Locals.VariableDescription(19, 31, "q", "F", null, 6), - new Locals.VariableDescription(55, 37, "o", "Ljava/lang/Object;", null, 3), - new Locals.VariableDescription(0, 92, "this", "Lart/Target;", null, 14), - new Locals.VariableDescription(12, 80, "z", "I", null, 8), - new Locals.VariableDescription(11, 81, "y", "I", null, 5), - new Locals.VariableDescription(62, 30, "p", "I", null, 4), - new Locals.VariableDescription(0, 92, "x", "I", null, 15), - new Locals.VariableDescription(27, 23, "i", "D", null, 0), - new Locals.VariableDescription(65, 27, "q", "J", null, 6), - new Locals.VariableDescription(60, - 32, + new Locals.VariableDescription(20, 28, "q", "F", null, 4), + new Locals.VariableDescription(56, 34, "o", "Ljava/lang/Object;", null, 3), + new Locals.VariableDescription(0, 90, "this", "Lart/Target;", null, 12), + new Locals.VariableDescription(12, 39, "z", "I", null, 3), + new Locals.VariableDescription(11, 79, "y", "I", null, 1), + new Locals.VariableDescription(63, 27, "p", "I", null, 6), + new Locals.VariableDescription(0, 90, "x", "I", null, 13), + new Locals.VariableDescription(31, 17, "i", "D", null, 8), + new Locals.VariableDescription(66, 24, "q", "J", null, 7), + new Locals.VariableDescription(61, + 29, "i", "Ljava/util/ArrayList;", "Ljava/util/ArrayList<Ljava/lang/Integer;>;", - 2))), + 4))), + }; + + public static Set<Locals.VariableDescription>[] TEST_GENERIC_PARAMETERS_VARIABLES = new Set[] { + // RI Local variable table + new HashSet<>(Arrays.asList( + new Locals.VariableDescription(0, 8, "this", "Lart/Target;", null, 0), + new Locals.VariableDescription(0, + 8, + "array", + "Ljava/util/ArrayList;", + "Ljava/util/ArrayList<Ljava/lang/Integer;>;", + 1), + new Locals.VariableDescription(0, 8, "i", "I", null, 2), + new Locals.VariableDescription(0, 8, "val", "Ljava/lang/Integer;", null, 3))), + // ART Local variable table + new HashSet<>(Arrays.asList( + new Locals.VariableDescription(0, 4, "this", "Lart/Target;", null, 0), + new Locals.VariableDescription(0, + 4, + "array", + "Ljava/util/ArrayList;", + "Ljava/util/ArrayList<Ljava/lang/Integer;>;", + 1), + new Locals.VariableDescription(0, 4, "i", "I", null, 2), + new Locals.VariableDescription(0, 4, "val", "Ljava/lang/Integer;", null, 3))), }; + // Get a classloader that can load the Target class. public static ClassLoader getClassLoader() throws Exception { try { @@ -213,6 +259,9 @@ public class Test1911 { DO_NOTHING_VARIABLES); CheckLocalVariableTable(target.getDeclaredMethod("doSomething", Integer.TYPE), DO_SOMETHING_VARIABLES); + CheckLocalVariableTable(target.getDeclaredMethod("testGenericParameters", + (new ArrayList<Integer>(0)).getClass(), Integer.TYPE, (new Integer(0)).getClass()), + TEST_GENERIC_PARAMETERS_VARIABLES); } } diff --git a/test/913-heaps/src/art/Test913.java b/test/913-heaps/src/art/Test913.java index 4fffa88198..8bd7cf4710 100644 --- a/test/913-heaps/src/art/Test913.java +++ b/test/913-heaps/src/art/Test913.java @@ -317,7 +317,8 @@ public class Test913 { BufferedReader reader = new BufferedReader(new FileReader("/proc/" + pid + "/maps")); String line; while ((line = reader.readLine()) != null) { - if (line.endsWith(".art")) { + // On host the mappings end with .art and on device they end with .art] + if (line.endsWith(".art]") || line.endsWith(".art")) { reader.close(); return true; } diff --git a/test/dexpreopt/dexpreopt_test.cc b/test/dexpreopt/dexpreopt_test.cc index 9641e0adf1..eac84f5517 100644 --- a/test/dexpreopt/dexpreopt_test.cc +++ b/test/dexpreopt/dexpreopt_test.cc @@ -198,12 +198,7 @@ android::base::Result<std::vector<std::string>> GetSystemServerArtifactsMappedOd if (pids.size() != 1) { return Errorf("There should be exactly one `system_server` process, found {}", pids.size()); } - // Unlike boot images, app images don't get unmapped if the runtime rejects them in some cases - // (e.g., CLC mismatch). Therefore, we need to check the PROT_EXEC flag to ensure that they are - // valid. - // The ODEX files always contain executable code because system server jars are compiled with the - // "speed" filter. - return GetMappedFiles(pids[0], ".odex", PROT_EXEC); + return GetMappedFiles(pids[0], ".odex", PROT_READ); } TEST(DexpreoptTest, ForZygote) { diff --git a/tools/build-linux-x86-host-tools.sh b/tools/build-linux-x86-host-tools.sh new file mode 100755 index 0000000000..c0483fa97c --- /dev/null +++ b/tools/build-linux-x86-host-tools.sh @@ -0,0 +1,56 @@ + #!/bin/bash +# +# Copyright (C) 2023 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. + +set -e + +if [ ! -e 'build/make/core/Makefile' ]; then + echo "Script $0 needs to be run at the root of the android tree" + exit 1 +fi + +vars="$(build/soong/soong_ui.bash --dumpvars-mode --vars="OUT_DIR DIST_DIR")" +# Assign to a variable and eval that, since bash ignores any error status from +# the command substitution if it's directly on the eval line. +eval $vars + +HOST_BINARIES=( + ${OUT_DIR}/host/linux-x86/bin/dex2oat64 + ${OUT_DIR}/host/linux-x86/bin/dex2oatd64 + ${OUT_DIR}/host/linux-x86/bin/dex2oat + ${OUT_DIR}/host/linux-x86/bin/dex2oatd + ${OUT_DIR}/host/linux-x86/bin/deapexer + ${OUT_DIR}/host/linux-x86/bin/debugfs_static + ${OUT_DIR}/host/linux-x86/bin/oatdump +) + +# Build statically linked musl binaries for linux-x86 hosts without the +# standard glibc implementation. +build/soong/soong_ui.bash --make-mode USE_HOST_MUSL=true BUILD_HOST_static=true ${HOST_BINARIES[*]} +# Zip these binaries in a temporary file +prebuilts/build-tools/linux-x86/bin/soong_zip -o "${DIST_DIR}/temp-host-tools.zip" \ + -j ${HOST_BINARIES[*]/#/-f } + +# Build art_release.zip and copy only art jars in a temporary zip +build/soong/soong_ui.bash --make-mode dist "${DIST_DIR}/art_release.zip" +prebuilts/build-tools/linux-x86/bin/zip2zip -i "${DIST_DIR}/art_release.zip" \ + -o "${DIST_DIR}/temp-art-jars.zip" "bootjars/*" + +# Merge both temporary zips into output zip +prebuilts/build-tools/linux-x86/bin/merge_zips "${DIST_DIR}/art-host-tools-linux-x86.zip" \ + "${DIST_DIR}/temp-host-tools.zip" "${DIST_DIR}/temp-art-jars.zip" + +# Delete temporary zips +rm "${DIST_DIR}/temp-host-tools.zip" "${DIST_DIR}/temp-art-jars.zip" |