Merge changes from topic "ext-dex-signature-arg"
* changes:
Rename libdexfile external API header.
Expose PrettyMethod's with_signature in GetMethodInfoForOffset.
diff --git a/Android.mk b/Android.mk
index 237dcd8..a2d8f64 100644
--- a/Android.mk
+++ b/Android.mk
@@ -63,7 +63,6 @@
include $(art_path)/tools/amm/Android.mk
include $(art_path)/tools/dexfuzz/Android.mk
include $(art_path)/tools/veridex/Android.mk
-include $(art_path)/libart_fake/Android.mk
ART_HOST_DEPENDENCIES := \
$(ART_HOST_EXECUTABLES) \
@@ -388,9 +387,6 @@
profman \
libadbconnection \
-# For nosy apps, we provide a fake library that avoids namespace issues and gives some warnings.
-LOCAL_REQUIRED_MODULES += libart_fake
-
# Potentially add in debug variants:
#
# * We will never add them if PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD = false.
diff --git a/compiler/jni/quick/arm/calling_convention_arm.cc b/compiler/jni/quick/arm/calling_convention_arm.cc
index 8b4bab7..42a4603 100644
--- a/compiler/jni/quick/arm/calling_convention_arm.cc
+++ b/compiler/jni/quick/arm/calling_convention_arm.cc
@@ -18,6 +18,7 @@
#include <android-base/logging.h>
+#include "arch/instruction_set.h"
#include "base/macros.h"
#include "handle_scope-inl.h"
#include "utils/arm/managed_register_arm.h"
diff --git a/compiler/jni/quick/arm64/calling_convention_arm64.cc b/compiler/jni/quick/arm64/calling_convention_arm64.cc
index 4e6221e..4a6a754 100644
--- a/compiler/jni/quick/arm64/calling_convention_arm64.cc
+++ b/compiler/jni/quick/arm64/calling_convention_arm64.cc
@@ -18,6 +18,7 @@
#include <android-base/logging.h>
+#include "arch/instruction_set.h"
#include "handle_scope-inl.h"
#include "utils/arm64/managed_register_arm64.h"
diff --git a/compiler/jni/quick/calling_convention.cc b/compiler/jni/quick/calling_convention.cc
index ff814c8..f031b9b 100644
--- a/compiler/jni/quick/calling_convention.cc
+++ b/compiler/jni/quick/calling_convention.cc
@@ -18,6 +18,8 @@
#include <android-base/logging.h>
+#include "arch/instruction_set.h"
+
#ifdef ART_ENABLE_CODEGEN_arm
#include "jni/quick/arm/calling_convention_arm.h"
#endif
diff --git a/compiler/jni/quick/calling_convention.h b/compiler/jni/quick/calling_convention.h
index e256ce6..77a5d59 100644
--- a/compiler/jni/quick/calling_convention.h
+++ b/compiler/jni/quick/calling_convention.h
@@ -27,6 +27,8 @@
namespace art {
+enum class InstructionSet;
+
// Top-level abstraction for different calling conventions.
class CallingConvention : public DeletableArenaObject<kArenaAllocCallingConvention> {
public:
diff --git a/compiler/jni/quick/mips/calling_convention_mips.cc b/compiler/jni/quick/mips/calling_convention_mips.cc
index d3d489e..c69854d 100644
--- a/compiler/jni/quick/mips/calling_convention_mips.cc
+++ b/compiler/jni/quick/mips/calling_convention_mips.cc
@@ -18,6 +18,7 @@
#include <android-base/logging.h>
+#include "arch/instruction_set.h"
#include "handle_scope-inl.h"
#include "utils/mips/managed_register_mips.h"
diff --git a/compiler/jni/quick/mips64/calling_convention_mips64.cc b/compiler/jni/quick/mips64/calling_convention_mips64.cc
index 3c7cee6..2c297b3 100644
--- a/compiler/jni/quick/mips64/calling_convention_mips64.cc
+++ b/compiler/jni/quick/mips64/calling_convention_mips64.cc
@@ -18,6 +18,7 @@
#include <android-base/logging.h>
+#include "arch/instruction_set.h"
#include "handle_scope-inl.h"
#include "utils/mips64/managed_register_mips64.h"
diff --git a/compiler/jni/quick/x86/calling_convention_x86.cc b/compiler/jni/quick/x86/calling_convention_x86.cc
index 71e6019..1f255e2 100644
--- a/compiler/jni/quick/x86/calling_convention_x86.cc
+++ b/compiler/jni/quick/x86/calling_convention_x86.cc
@@ -18,6 +18,7 @@
#include <android-base/logging.h>
+#include "arch/instruction_set.h"
#include "handle_scope-inl.h"
#include "utils/x86/managed_register_x86.h"
diff --git a/compiler/jni/quick/x86_64/calling_convention_x86_64.cc b/compiler/jni/quick/x86_64/calling_convention_x86_64.cc
index e5e96d0..9e77d6b 100644
--- a/compiler/jni/quick/x86_64/calling_convention_x86_64.cc
+++ b/compiler/jni/quick/x86_64/calling_convention_x86_64.cc
@@ -18,6 +18,7 @@
#include <android-base/logging.h>
+#include "arch/instruction_set.h"
#include "base/bit_utils.h"
#include "handle_scope-inl.h"
#include "utils/x86_64/managed_register_x86_64.h"
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index fd454f0..524bce0 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -1011,6 +1011,10 @@
}
TEST_F(Dex2oatWatchdogTest, TestWatchdogTrigger) {
+ // This test is frequently interrupted by timeout_dumper on host (x86);
+ // disable it while we investigate (b/121352534).
+ TEST_DISABLED_FOR_X86();
+
// The watchdog is independent of dex2oat and will not delete intermediates. It is possible
// that the compilation succeeds and the file is completely written by the time the watchdog
// kills dex2oat (but the dex2oat threads must have been scheduled pretty badly).
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index 1331fc3..15ced72 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -49,6 +49,7 @@
#include "gc/heap-visit-objects-inl.h"
#include "gc/heap.h"
#include "gc/space/large_object_space.h"
+#include "gc/space/region_space.h"
#include "gc/space/space-inl.h"
#include "gc/verification.h"
#include "handle_scope-inl.h"
@@ -2423,10 +2424,33 @@
}
// Calculate bin slot offsets.
- for (ImageInfo& image_info : image_infos_) {
+ for (size_t oat_index = 0; oat_index < image_infos_.size(); ++oat_index) {
+ ImageInfo& image_info = image_infos_[oat_index];
size_t bin_offset = image_objects_offset_begin_;
+ // Need to visit the objects in bin order since alignment requirements might change the
+ // section sizes.
+ // Avoid using ObjPtr since VisitObjects invalidates. This is safe since concurrent GC can not
+ // occur during image writing.
+ using BinPair = std::pair<BinSlot, mirror::Object*>;
+ std::vector<BinPair> objects;
+ heap->VisitObjects([&](mirror::Object* obj)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ // Only visit the oat index for the current image.
+ if (IsImageObject(obj) && GetOatIndex(obj) == oat_index) {
+ objects.emplace_back(GetImageBinSlot(obj), obj);
+ }
+ });
+ std::sort(objects.begin(), objects.end(), [](const BinPair& a, const BinPair& b) -> bool {
+ if (a.first.GetBin() != b.first.GetBin()) {
+ return a.first.GetBin() < b.first.GetBin();
+ }
+ // Note that the index is really the relative offset in this case.
+ return a.first.GetIndex() < b.first.GetIndex();
+ });
+ auto it = objects.begin();
for (size_t i = 0; i != kNumberOfBins; ++i) {
- switch (static_cast<Bin>(i)) {
+ Bin bin = enum_cast<Bin>(i);
+ switch (bin) {
case Bin::kArtMethodClean:
case Bin::kArtMethodDirty: {
bin_offset = RoundUp(bin_offset, method_alignment);
@@ -2445,13 +2469,49 @@
}
}
image_info.bin_slot_offsets_[i] = bin_offset;
- bin_offset += image_info.bin_slot_sizes_[i];
+
+ // If the bin is for mirror objects, assign the offsets since we may need to change sizes
+ // from alignment requirements.
+ if (i < static_cast<size_t>(Bin::kMirrorCount)) {
+ const size_t start_offset = bin_offset;
+ // Visit and assign offsets for all objects of the bin type.
+ while (it != objects.end() && it->first.GetBin() == bin) {
+ ObjPtr<mirror::Object> obj(it->second);
+ const size_t object_size = RoundUp(obj->SizeOf(), kObjectAlignment);
+ // If the object spans region bondaries, add padding objects between.
+ // TODO: Instead of adding padding, we should consider reordering the bins to reduce
+ // wasted space.
+ if (region_size_ != 0u) {
+ const size_t offset_after_header = bin_offset - sizeof(ImageHeader);
+ const size_t next_region = RoundUp(offset_after_header, region_size_);
+ if (offset_after_header != next_region &&
+ offset_after_header + object_size > next_region) {
+ // Add padding objects until aligned.
+ while (bin_offset - sizeof(ImageHeader) < next_region) {
+ image_info.padding_object_offsets_.push_back(bin_offset);
+ bin_offset += kObjectAlignment;
+ region_alignment_wasted_ += kObjectAlignment;
+ image_info.image_end_ += kObjectAlignment;
+ }
+ CHECK_EQ(bin_offset - sizeof(ImageHeader), next_region);
+ }
+ }
+ SetImageOffset(obj.Ptr(), bin_offset);
+ bin_offset = bin_offset + object_size;
+ ++it;
+ }
+ image_info.bin_slot_sizes_[i] = bin_offset - start_offset;
+ } else {
+ bin_offset += image_info.bin_slot_sizes_[i];
+ }
}
// NOTE: There may be additional padding between the bin slots and the intern table.
DCHECK_EQ(image_info.image_end_,
image_info.GetBinSizeSum(Bin::kMirrorCount) + image_objects_offset_begin_);
}
+ VLOG(image) << "Space wasted for region alignment " << region_alignment_wasted_;
+
// Calculate image offsets.
size_t image_offset = 0;
for (ImageInfo& image_info : image_infos_) {
@@ -2462,17 +2522,6 @@
image_offset += image_info.image_size_;
}
- // Transform each object's bin slot into an offset which will be used to do the final copy.
- {
- auto unbin_objects_into_offset = [&](mirror::Object* obj)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- if (IsImageObject(obj)) {
- UnbinObjectsIntoOffset(obj);
- }
- };
- heap->VisitObjects(unbin_objects_into_offset);
- }
-
size_t i = 0;
for (ImageInfo& image_info : image_infos_) {
image_info.image_roots_address_ = PointerToLowMemUInt32(GetImageAddress(image_roots[i].Get()));
@@ -2887,16 +2936,6 @@
}
}
-void ImageWriter::CopyAndFixupObjects() {
- auto visitor = [&](Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK(obj != nullptr);
- CopyAndFixupObject(obj);
- };
- Runtime::Current()->GetHeap()->VisitObjects(visitor);
- // We no longer need the hashcode map, values have already been copied to target objects.
- saved_hashcode_map_.clear();
-}
-
void ImageWriter::FixupPointerArray(mirror::Object* dst,
mirror::PointerArray* arr,
Bin array_type) {
@@ -2944,6 +2983,18 @@
image_info.image_bitmap_->Set(dst); // Mark the obj as live.
const size_t n = obj->SizeOf();
+
+ if (kIsDebugBuild && region_size_ != 0u) {
+ const size_t offset_after_header = offset - sizeof(ImageHeader);
+ const size_t next_region = RoundUp(offset_after_header, region_size_);
+ if (offset_after_header != next_region) {
+ // If the object is not on a region bondary, it must not be cross region.
+ CHECK_LT(offset_after_header, next_region)
+ << "offset_after_header=" << offset_after_header << " size=" << n;
+ CHECK_LE(offset_after_header + n, next_region)
+ << "offset_after_header=" << offset_after_header << " size=" << n;
+ }
+ }
DCHECK_LE(offset + n, image_info.image_.Size());
memcpy(dst, src, n);
@@ -2973,7 +3024,6 @@
const {}
void VisitRoot(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) const {}
-
void operator()(ObjPtr<Object> obj, MemberOffset offset, bool is_static ATTRIBUTE_UNUSED) const
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_) {
ObjPtr<Object> ref = obj->GetFieldObject<Object, kVerifyNone>(offset);
@@ -2994,6 +3044,25 @@
mirror::Object* const copy_;
};
+void ImageWriter::CopyAndFixupObjects() {
+ auto visitor = [&](Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
+ DCHECK(obj != nullptr);
+ CopyAndFixupObject(obj);
+ };
+ Runtime::Current()->GetHeap()->VisitObjects(visitor);
+ // Copy the padding objects since they are required for in order traversal of the image space.
+ for (const ImageInfo& image_info : image_infos_) {
+ for (const size_t offset : image_info.padding_object_offsets_) {
+ auto* dst = reinterpret_cast<Object*>(image_info.image_.Begin() + offset);
+ dst->SetClass<kVerifyNone>(GetImageAddress(GetClassRoot<mirror::Object>().Ptr()));
+ dst->SetLockWord<kVerifyNone>(LockWord::Default(), /*as_volatile=*/ false);
+ image_info.image_bitmap_->Set(dst); // Mark the obj as live.
+ }
+ }
+ // We no longer need the hashcode map, values have already been copied to target objects.
+ saved_hashcode_map_.clear();
+}
+
class ImageWriter::FixupClassVisitor final : public FixupVisitor {
public:
FixupClassVisitor(ImageWriter* image_writer, Object* copy)
@@ -3572,6 +3641,10 @@
CHECK_EQ(compiler_options.IsBootImage(),
Runtime::Current()->GetHeap()->GetBootImageSpaces().empty())
<< "Compiling a boot image should occur iff there are no boot image spaces loaded";
+ if (compiler_options_.IsAppImage()) {
+ // Make sure objects are not crossing region boundaries for app images.
+ region_size_ = gc::space::RegionSpace::kRegionSize;
+ }
}
ImageWriter::ImageInfo::ImageInfo()
diff --git a/dex2oat/linker/image_writer.h b/dex2oat/linker/image_writer.h
index b680265..8896e07 100644
--- a/dex2oat/linker/image_writer.h
+++ b/dex2oat/linker/image_writer.h
@@ -279,7 +279,7 @@
private:
// Must be the same size as LockWord, any larger and we would truncate the data.
- const uint32_t lockword_;
+ uint32_t lockword_;
};
struct ImageInfo {
@@ -397,6 +397,9 @@
// Class table associated with this image for serialization.
std::unique_ptr<ClassTable> class_table_;
+
+ // Padding objects to ensure region alignment (if required).
+ std::vector<size_t> padding_object_offsets_;
};
// We use the lock word to store the offset of the object in the image.
@@ -798,6 +801,12 @@
// Set of objects known to be dirty in the image. Can be nullptr if there are none.
const HashSet<std::string>* dirty_image_objects_;
+ // Objects are guaranteed to not cross the region size boundary.
+ size_t region_size_ = 0u;
+
+ // Region alignment bytes wasted.
+ size_t region_alignment_wasted_ = 0u;
+
class ImageFileGuard;
class FixupClassVisitor;
class FixupRootVisitor;
diff --git a/dex2oat/linker/oat_writer.h b/dex2oat/linker/oat_writer.h
index cc0e83a..48215bb 100644
--- a/dex2oat/linker/oat_writer.h
+++ b/dex2oat/linker/oat_writer.h
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <cstddef>
+#include <list>
#include <memory>
#include <vector>
diff --git a/libart_fake/Android.mk b/libart_fake/Android.mk
deleted file mode 100644
index 96e6a14..0000000
--- a/libart_fake/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2016 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.
-#
-
-LOCAL_PATH := $(my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libart_fake
-LOCAL_INSTALLED_MODULE_STEM := libart.so
-LOCAL_SDK_VERSION := 9
-LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := fake.cc
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SHARED_LIBRARIES := liblog
-
-ifdef TARGET_2ND_ARCH
- LOCAL_MODULE_PATH_32 := $(TARGET_OUT)/fake-libs
- LOCAL_MODULE_PATH_64 := $(TARGET_OUT)/fake-libs64
-else
- LOCAL_MODULE_PATH := $(TARGET_OUT)/fake-libs
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libart_fake/README.md b/libart_fake/README.md
deleted file mode 100644
index 6e3621e..0000000
--- a/libart_fake/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-libart_fake
-====
-
-A fake libart made to satisfy some misbehaving apps that will attempt to link
-against libart.so.
diff --git a/libart_fake/fake.cc b/libart_fake/fake.cc
deleted file mode 100644
index 8842421..0000000
--- a/libart_fake/fake.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2016 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.
- */
-
-#define LOG_TAG "libart_fake"
-
-#include <android/log.h>
-
-#define LOGIT(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
-namespace art {
-class Dbg {
- public:
- void SuspendVM();
- void ResumeVM();
-};
-
-class FaultManager {
- public:
- void EnsureArtActionInFrontOfSignalChain();
-};
-
-void Dbg::SuspendVM() {
- LOGIT("Linking to and calling into libart.so internal functions is not supported. "
- "This call to '%s' is being ignored.", __func__);
-}
-void Dbg::ResumeVM() {
- LOGIT("Linking to and calling into libart.so internal functions is not supported. "
- "This call to '%s' is being ignored.", __func__);
-}
-void FaultManager::EnsureArtActionInFrontOfSignalChain() {
- LOGIT("Linking to and calling into libart.so internal functions is not supported. "
- "This call to '%s' is being ignored.", __func__);
-}
-}; // namespace art
diff --git a/libartbase/Android.bp b/libartbase/Android.bp
index 109853c..509b072 100644
--- a/libartbase/Android.bp
+++ b/libartbase/Android.bp
@@ -24,6 +24,7 @@
"base/arena_allocator.cc",
"base/arena_bit_vector.cc",
"base/bit_vector.cc",
+ "base/enums.cc",
"base/file_magic.cc",
"base/file_utils.cc",
"base/hex_dump.cc",
@@ -153,7 +154,6 @@
srcs: [
"arch/instruction_set.h",
"base/allocator.h",
- "base/callee_save_type.h",
"base/unix_file/fd_file.h",
],
output_extension: "operator_out.cc",
diff --git a/libartbase/base/enums.cc b/libartbase/base/enums.cc
new file mode 100644
index 0000000..3f28232
--- /dev/null
+++ b/libartbase/base/enums.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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 "enums.h"
+
+#include <ostream>
+
+namespace art {
+
+std::ostream& operator<<(std::ostream& os, const PointerSize& rhs) {
+ switch (rhs) {
+ case PointerSize::k32: os << "k32"; break;
+ case PointerSize::k64: os << "k64"; break;
+ default: os << "PointerSize[" << static_cast<int>(rhs) << "]"; break;
+ }
+ return os;
+}
+
+} // namespace art
diff --git a/libartbase/base/enums.h b/libartbase/base/enums.h
index ad5578f..c5fb880 100644
--- a/libartbase/base/enums.h
+++ b/libartbase/base/enums.h
@@ -18,7 +18,7 @@
#define ART_LIBARTBASE_BASE_ENUMS_H_
#include <cstddef>
-#include <ostream>
+#include <iosfwd>
namespace art {
@@ -27,14 +27,7 @@
k64 = 8
};
-inline std::ostream& operator<<(std::ostream& os, const PointerSize& rhs) {
- switch (rhs) {
- case PointerSize::k32: os << "k32"; break;
- case PointerSize::k64: os << "k64"; break;
- default: os << "PointerSize[" << static_cast<int>(rhs) << "]"; break;
- }
- return os;
-}
+std::ostream& operator<<(std::ostream& os, const PointerSize& rhs);
static constexpr PointerSize kRuntimePointerSize = sizeof(void*) == 8U
? PointerSize::k64
diff --git a/libartbase/base/globals.h b/libartbase/base/globals.h
index 2a2a737..97eae63 100644
--- a/libartbase/base/globals.h
+++ b/libartbase/base/globals.h
@@ -38,20 +38,6 @@
// compile-time constant so the compiler can generate better code.
static constexpr int kPageSize = 4096;
-// Size of Dex virtual registers.
-static constexpr size_t kVRegSize = 4;
-
-// Returns whether the given memory offset can be used for generating
-// an implicit null check.
-static inline bool CanDoImplicitNullCheckOn(uintptr_t offset) {
- return offset < kPageSize;
-}
-
-// Required object alignment
-static constexpr size_t kObjectAlignmentShift = 3;
-static constexpr size_t kObjectAlignment = 1u << kObjectAlignmentShift;
-static constexpr size_t kLargeObjectAlignment = kPageSize;
-
// Clion, clang analyzer, etc can falsely believe that "if (kIsDebugBuild)" always
// returns the same value. By wrapping into a call to another constexpr function, we force it
// to realize that is not actually always evaluating to the same value.
@@ -117,48 +103,6 @@
static constexpr bool kHostStaticBuildEnabled = false;
#endif
-// Garbage collector constants.
-static constexpr bool kMovingCollector = true;
-static constexpr bool kMarkCompactSupport = false && kMovingCollector;
-// True if we allow moving classes.
-static constexpr bool kMovingClasses = !kMarkCompactSupport;
-// If true, enable generational collection when using the Concurrent Copying
-// (CC) collector, i.e. use sticky-bit CC for minor collections and (full) CC
-// for major collections.
-//
-// Generational CC collection is currently only compatible with Baker read
-// barriers.
-#if defined(ART_USE_GENERATIONAL_CC) && defined(ART_READ_BARRIER_TYPE_IS_BAKER)
-static constexpr bool kEnableGenerationalConcurrentCopyingCollection = true;
-#else
-static constexpr bool kEnableGenerationalConcurrentCopyingCollection = false;
-#endif
-
-// If true, enable the tlab allocator by default.
-#ifdef ART_USE_TLAB
-static constexpr bool kUseTlab = true;
-#else
-static constexpr bool kUseTlab = false;
-#endif
-
-// Kinds of tracing clocks.
-enum class TraceClockSource {
- kThreadCpu,
- kWall,
- kDual, // Both wall and thread CPU clocks.
-};
-
-#if defined(__linux__)
-static constexpr TraceClockSource kDefaultTraceClockSource = TraceClockSource::kDual;
-#else
-static constexpr TraceClockSource kDefaultTraceClockSource = TraceClockSource::kWall;
-#endif
-
-static constexpr bool kDefaultMustRelocate = true;
-
-// Size of a heap reference.
-static constexpr size_t kHeapReferenceSize = sizeof(uint32_t);
-
} // namespace art
#endif // ART_LIBARTBASE_BASE_GLOBALS_H_
diff --git a/libartbase/base/logging.h b/libartbase/base/logging.h
index 9ded082..484db87 100644
--- a/libartbase/base/logging.h
+++ b/libartbase/base/logging.h
@@ -17,9 +17,6 @@
#ifndef ART_LIBARTBASE_BASE_LOGGING_H_
#define ART_LIBARTBASE_BASE_LOGGING_H_
-#include <ostream>
-#include <sstream>
-
#include "android-base/logging.h"
#include "macros.h"
diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc
index 5c100e6..d3cdf13 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -23,6 +23,7 @@
#include <zlib.h>
#include <memory>
+#include <ostream>
#include <sstream>
#include <type_traits>
diff --git a/libdexfile/dex/dex_file_types.h b/libdexfile/dex/dex_file_types.h
index d4fb3de..ecc0482 100644
--- a/libdexfile/dex/dex_file_types.h
+++ b/libdexfile/dex/dex_file_types.h
@@ -17,8 +17,9 @@
#ifndef ART_LIBDEXFILE_DEX_DEX_FILE_TYPES_H_
#define ART_LIBDEXFILE_DEX_DEX_FILE_TYPES_H_
+#include <iosfwd>
#include <limits>
-#include <ostream>
+#include <utility>
namespace art {
namespace dex {
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 4e1276e..89826c6 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -114,7 +114,7 @@
"kOomeWhenThrowingOome",
"kOomeWhenHandlingStackOverflow",
"kNoClassDefFoundError",
- "kClassLoader",
+ "kSpecialRoots",
};
// Map is so that we don't allocate multiple dex files for the same OatDexFile.
diff --git a/openjdkjvmti/OpenjdkJvmTi.cc b/openjdkjvmti/OpenjdkJvmTi.cc
index bd5b598..7a2b638 100644
--- a/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/openjdkjvmti/OpenjdkJvmTi.cc
@@ -1552,7 +1552,7 @@
{
// Make sure we can deopt anything we need to.
- art::ScopedObjectAccess soa(art::Thread::Current());
+ art::ScopedSuspendAll ssa(__FUNCTION__);
gDeoptManager->FinishSetup();
}
diff --git a/openjdkjvmti/deopt_manager.h b/openjdkjvmti/deopt_manager.h
index d9f34a5..065baa7 100644
--- a/openjdkjvmti/deopt_manager.h
+++ b/openjdkjvmti/deopt_manager.h
@@ -107,7 +107,7 @@
void FinishSetup()
REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
- REQUIRES_SHARED(art::Locks::mutator_lock_);
+ REQUIRES(art::Locks::mutator_lock_);
static DeoptManager* Get();
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index 7fb6a15..22c622a 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -34,6 +34,7 @@
#include <array>
#include <sys/time.h>
+#include "arch/context.h"
#include "art_field-inl.h"
#include "art_jvmti.h"
#include "art_method-inl.h"
diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc
index 7d69c89..e88539f 100644
--- a/openjdkjvmti/ti_method.cc
+++ b/openjdkjvmti/ti_method.cc
@@ -33,6 +33,7 @@
#include <type_traits>
+#include "arch/context.h"
#include "art_jvmti.h"
#include "art_method-inl.h"
#include "base/enums.h"
diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc
index 4bcb7b2..3d175a8 100644
--- a/openjdkjvmti/ti_redefine.cc
+++ b/openjdkjvmti/ti_redefine.cc
@@ -188,7 +188,9 @@
if (obsoleted_methods_.find(old_method) != obsoleted_methods_.end()) {
// We cannot ensure that the right dex file is used in inlined frames so we don't support
// redefining them.
- DCHECK(!IsInInlinedFrame()) << "Inlined frames are not supported when using redefinition";
+ DCHECK(!IsInInlinedFrame()) << "Inlined frames are not supported when using redefinition: "
+ << old_method->PrettyMethod() << " is inlined into "
+ << GetOuterMethod()->PrettyMethod();
art::ArtMethod* new_obsolete_method = obsolete_maps_->FindObsoleteVersion(old_method);
if (new_obsolete_method == nullptr) {
// Create a new Obsolete Method and put it in the list.
diff --git a/openjdkjvmti/ti_stack.cc b/openjdkjvmti/ti_stack.cc
index 4a3eac8..385ac45 100644
--- a/openjdkjvmti/ti_stack.cc
+++ b/openjdkjvmti/ti_stack.cc
@@ -36,6 +36,7 @@
#include <unordered_map>
#include <vector>
+#include "arch/context.h"
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "art_jvmti.h"
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 71c5b74..b89eb02 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -462,6 +462,7 @@
cmd: "$(location generate_operator_out) art/runtime $(in) > $(out)",
tools: ["generate_operator_out"],
srcs: [
+ "base/callee_save_type.h",
"base/locks.h",
"class_loader_context.h",
"class_status.h",
diff --git a/runtime/arch/arm/callee_save_frame_arm.h b/runtime/arch/arm/callee_save_frame_arm.h
index 11eefb9..72ba3b7 100644
--- a/runtime/arch/arm/callee_save_frame_arm.h
+++ b/runtime/arch/arm/callee_save_frame_arm.h
@@ -21,9 +21,9 @@
#include "base/bit_utils.h"
#include "base/callee_save_type.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "quick/quick_method_frame_info.h"
#include "registers_arm.h"
+#include "runtime_globals.h"
namespace art {
namespace arm {
diff --git a/runtime/arch/arm/fault_handler_arm.cc b/runtime/arch/arm/fault_handler_arm.cc
index bb33a27..e186cd3 100644
--- a/runtime/arch/arm/fault_handler_arm.cc
+++ b/runtime/arch/arm/fault_handler_arm.cc
@@ -18,12 +18,13 @@
#include <sys/ucontext.h>
+#include "arch/instruction_set.h"
#include "art_method.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "base/hex_dump.h"
#include "base/logging.h" // For VLOG.
#include "base/macros.h"
+#include "runtime_globals.h"
#include "thread-current-inl.h"
//
diff --git a/runtime/arch/arm64/callee_save_frame_arm64.h b/runtime/arch/arm64/callee_save_frame_arm64.h
index a5aea2a..d3609f1 100644
--- a/runtime/arch/arm64/callee_save_frame_arm64.h
+++ b/runtime/arch/arm64/callee_save_frame_arm64.h
@@ -21,9 +21,9 @@
#include "base/bit_utils.h"
#include "base/callee_save_type.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "quick/quick_method_frame_info.h"
#include "registers_arm64.h"
+#include "runtime_globals.h"
namespace art {
namespace arm64 {
diff --git a/runtime/arch/arm64/fault_handler_arm64.cc b/runtime/arch/arm64/fault_handler_arm64.cc
index e8b4627..751c05b 100644
--- a/runtime/arch/arm64/fault_handler_arm64.cc
+++ b/runtime/arch/arm64/fault_handler_arm64.cc
@@ -18,13 +18,14 @@
#include <sys/ucontext.h>
+#include "arch/instruction_set.h"
#include "art_method.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "base/hex_dump.h"
#include "base/logging.h" // For VLOG.
#include "base/macros.h"
#include "registers_arm64.h"
+#include "runtime_globals.h"
#include "thread-current-inl.h"
extern "C" void art_quick_throw_stack_overflow();
diff --git a/runtime/arch/instruction_set_features.cc b/runtime/arch/instruction_set_features.cc
index 0c45bc9..886b40a 100644
--- a/runtime/arch/instruction_set_features.cc
+++ b/runtime/arch/instruction_set_features.cc
@@ -16,6 +16,9 @@
#include "instruction_set_features.h"
+#include <algorithm>
+#include <ostream>
+
#include "android-base/strings.h"
#include "base/casts.h"
diff --git a/runtime/arch/instruction_set_features.h b/runtime/arch/instruction_set_features.h
index c31c927..f910a41 100644
--- a/runtime/arch/instruction_set_features.h
+++ b/runtime/arch/instruction_set_features.h
@@ -17,8 +17,8 @@
#ifndef ART_RUNTIME_ARCH_INSTRUCTION_SET_FEATURES_H_
#define ART_RUNTIME_ARCH_INSTRUCTION_SET_FEATURES_H_
+#include <iosfwd>
#include <memory>
-#include <ostream>
#include <vector>
#include "arch/instruction_set.h"
diff --git a/runtime/arch/mips/callee_save_frame_mips.h b/runtime/arch/mips/callee_save_frame_mips.h
index 6e88d08..84ce209 100644
--- a/runtime/arch/mips/callee_save_frame_mips.h
+++ b/runtime/arch/mips/callee_save_frame_mips.h
@@ -21,9 +21,9 @@
#include "base/bit_utils.h"
#include "base/callee_save_type.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "quick/quick_method_frame_info.h"
#include "registers_mips.h"
+#include "runtime_globals.h"
namespace art {
namespace mips {
diff --git a/runtime/arch/mips/fault_handler_mips.cc b/runtime/arch/mips/fault_handler_mips.cc
index 7c8ac28..0354f0c 100644
--- a/runtime/arch/mips/fault_handler_mips.cc
+++ b/runtime/arch/mips/fault_handler_mips.cc
@@ -17,14 +17,15 @@
#include <sys/ucontext.h>
#include "fault_handler.h"
+#include "arch/instruction_set.h"
#include "arch/mips/callee_save_frame_mips.h"
#include "art_method.h"
#include "base/callee_save_type.h"
-#include "base/globals.h"
#include "base/hex_dump.h"
#include "base/logging.h" // For VLOG.
#include "base/macros.h"
#include "registers_mips.h"
+#include "runtime_globals.h"
#include "thread-current-inl.h"
extern "C" void art_quick_throw_stack_overflow();
diff --git a/runtime/arch/mips/registers_mips.h b/runtime/arch/mips/registers_mips.h
index 34f2f96..4900e41 100644
--- a/runtime/arch/mips/registers_mips.h
+++ b/runtime/arch/mips/registers_mips.h
@@ -19,9 +19,6 @@
#include <iosfwd>
-#include <android-base/logging.h>
-
-#include "base/globals.h"
#include "base/macros.h"
namespace art {
diff --git a/runtime/arch/mips64/callee_save_frame_mips64.h b/runtime/arch/mips64/callee_save_frame_mips64.h
index 59529a0..64d6bec 100644
--- a/runtime/arch/mips64/callee_save_frame_mips64.h
+++ b/runtime/arch/mips64/callee_save_frame_mips64.h
@@ -21,9 +21,9 @@
#include "base/bit_utils.h"
#include "base/callee_save_type.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "quick/quick_method_frame_info.h"
#include "registers_mips64.h"
+#include "runtime_globals.h"
namespace art {
namespace mips64 {
diff --git a/runtime/arch/mips64/fault_handler_mips64.cc b/runtime/arch/mips64/fault_handler_mips64.cc
index 85f3528..6255235 100644
--- a/runtime/arch/mips64/fault_handler_mips64.cc
+++ b/runtime/arch/mips64/fault_handler_mips64.cc
@@ -18,14 +18,15 @@
#include <sys/ucontext.h>
+#include "arch/instruction_set.h"
#include "arch/mips64/callee_save_frame_mips64.h"
#include "art_method.h"
#include "base/callee_save_type.h"
-#include "base/globals.h"
#include "base/hex_dump.h"
#include "base/logging.h" // For VLOG.
#include "base/macros.h"
#include "registers_mips64.h"
+#include "runtime_globals.h"
#include "thread-current-inl.h"
extern "C" void art_quick_throw_stack_overflow();
diff --git a/runtime/arch/mips64/registers_mips64.h b/runtime/arch/mips64/registers_mips64.h
index a3fa2ac4..1c22c07 100644
--- a/runtime/arch/mips64/registers_mips64.h
+++ b/runtime/arch/mips64/registers_mips64.h
@@ -19,9 +19,6 @@
#include <iosfwd>
-#include <android-base/logging.h>
-
-#include "base/globals.h"
#include "base/macros.h"
namespace art {
diff --git a/runtime/arch/x86/callee_save_frame_x86.h b/runtime/arch/x86/callee_save_frame_x86.h
index f336f43..2edcade 100644
--- a/runtime/arch/x86/callee_save_frame_x86.h
+++ b/runtime/arch/x86/callee_save_frame_x86.h
@@ -21,9 +21,9 @@
#include "base/bit_utils.h"
#include "base/callee_save_type.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "quick/quick_method_frame_info.h"
#include "registers_x86.h"
+#include "runtime_globals.h"
namespace art {
namespace x86 {
diff --git a/runtime/arch/x86/fault_handler_x86.cc b/runtime/arch/x86/fault_handler_x86.cc
index 8b24334..26312fb 100644
--- a/runtime/arch/x86/fault_handler_x86.cc
+++ b/runtime/arch/x86/fault_handler_x86.cc
@@ -18,13 +18,14 @@
#include <sys/ucontext.h>
+#include "arch/instruction_set.h"
#include "art_method.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "base/hex_dump.h"
#include "base/logging.h" // For VLOG.
#include "base/macros.h"
#include "base/safe_copy.h"
+#include "runtime_globals.h"
#include "thread-current-inl.h"
#if defined(__APPLE__)
diff --git a/runtime/arch/x86/registers_x86.h b/runtime/arch/x86/registers_x86.h
index d3b959f..ff6c18f 100644
--- a/runtime/arch/x86/registers_x86.h
+++ b/runtime/arch/x86/registers_x86.h
@@ -19,9 +19,6 @@
#include <iosfwd>
-#include <android-base/logging.h>
-
-#include "base/globals.h"
#include "base/macros.h"
namespace art {
diff --git a/runtime/arch/x86_64/callee_save_frame_x86_64.h b/runtime/arch/x86_64/callee_save_frame_x86_64.h
index 228a902..d4f2da7 100644
--- a/runtime/arch/x86_64/callee_save_frame_x86_64.h
+++ b/runtime/arch/x86_64/callee_save_frame_x86_64.h
@@ -21,9 +21,9 @@
#include "base/bit_utils.h"
#include "base/callee_save_type.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "quick/quick_method_frame_info.h"
#include "registers_x86_64.h"
+#include "runtime_globals.h"
namespace art {
namespace x86_64 {
diff --git a/runtime/arch/x86_64/registers_x86_64.h b/runtime/arch/x86_64/registers_x86_64.h
index 66aea70..248c82b 100644
--- a/runtime/arch/x86_64/registers_x86_64.h
+++ b/runtime/arch/x86_64/registers_x86_64.h
@@ -19,9 +19,6 @@
#include <iosfwd>
-#include <android-base/logging.h>
-
-#include "base/globals.h"
#include "base/macros.h"
namespace art {
diff --git a/runtime/art_method.h b/runtime/art_method.h
index aed9f62..aabd093 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -476,7 +476,7 @@
}
ProfilingInfo* GetProfilingInfo(PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_) {
- if (UNLIKELY(IsNative()) || UNLIKELY(IsProxyMethod())) {
+ if (UNLIKELY(IsNative() || IsProxyMethod() || !IsInvokable())) {
return nullptr;
}
return reinterpret_cast<ProfilingInfo*>(GetDataPtrSize(pointer_size));
diff --git a/libartbase/base/callee_save_type.h b/runtime/base/callee_save_type.h
similarity index 89%
rename from libartbase/base/callee_save_type.h
rename to runtime/base/callee_save_type.h
index 3e44a3a..e7cc7e6 100644
--- a/libartbase/base/callee_save_type.h
+++ b/runtime/base/callee_save_type.h
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-#ifndef ART_LIBARTBASE_BASE_CALLEE_SAVE_TYPE_H_
-#define ART_LIBARTBASE_BASE_CALLEE_SAVE_TYPE_H_
+#ifndef ART_RUNTIME_BASE_CALLEE_SAVE_TYPE_H_
+#define ART_RUNTIME_BASE_CALLEE_SAVE_TYPE_H_
-#include <cstddef>
-#include <ostream>
+#include <cstdint>
+#include <iosfwd>
namespace art {
@@ -44,4 +44,4 @@
} // namespace art
-#endif // ART_LIBARTBASE_BASE_CALLEE_SAVE_TYPE_H_
+#endif // ART_RUNTIME_BASE_CALLEE_SAVE_TYPE_H_
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index 41a47af..aaa1ee6 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -28,7 +28,7 @@
#include "base/aborting.h"
#include "base/atomic.h"
-#include "base/globals.h"
+#include "runtime_globals.h"
#include "base/macros.h"
#include "locks.h"
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 5d1f20c..d29a6b7 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -229,7 +229,9 @@
}
}
-void ClassLinker::ThrowEarlierClassFailure(ObjPtr<mirror::Class> c, bool wrap_in_no_class_def) {
+void ClassLinker::ThrowEarlierClassFailure(ObjPtr<mirror::Class> c,
+ bool wrap_in_no_class_def,
+ bool log) {
// The class failed to initialize on a previous attempt, so we want to throw
// a NoClassDefFoundError (v2 2.17.5). The exception to this rule is if we
// failed in verification, in which case v2 5.4.1 says we need to re-throw
@@ -245,8 +247,10 @@
extra = verify_error->AsThrowable()->Dump();
}
}
- LOG(INFO) << "Rejecting re-init on previously-failed class " << c->PrettyClass()
- << ": " << extra;
+ if (log) {
+ LOG(INFO) << "Rejecting re-init on previously-failed class " << c->PrettyClass()
+ << ": " << extra;
+ }
}
CHECK(c->IsErroneous()) << c->PrettyClass() << " " << c->GetStatus();
@@ -5044,7 +5048,7 @@
// Was the class already found to be erroneous? Done under the lock to match the JLS.
if (klass->IsErroneous()) {
- ThrowEarlierClassFailure(klass.Get(), true);
+ ThrowEarlierClassFailure(klass.Get(), true, /* log= */ true);
VlogClassInitializationFailure(klass);
return false;
}
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index b9ac9ca..4f4cb4b 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -17,6 +17,7 @@
#ifndef ART_RUNTIME_CLASS_LINKER_H_
#define ART_RUNTIME_CLASS_LINKER_H_
+#include <list>
#include <set>
#include <string>
#include <unordered_map>
@@ -89,6 +90,7 @@
class Runtime;
class ScopedObjectAccessAlreadyRunnable;
template<size_t kNumReferences> class PACKED(4) StackHandleScope;
+class Thread;
enum VisitRootFlags : uint8_t;
@@ -685,7 +687,9 @@
// Throw the class initialization failure recorded when first trying to initialize the given
// class.
- void ThrowEarlierClassFailure(ObjPtr<mirror::Class> c, bool wrap_in_no_class_def = false)
+ void ThrowEarlierClassFailure(ObjPtr<mirror::Class> c,
+ bool wrap_in_no_class_def = false,
+ bool log = false)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 29b7813..d7f6127 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -26,7 +26,6 @@
#include "arch/instruction_set.h"
#include "base/common_art_test.h"
-#include "base/globals.h"
#include "base/locks.h"
#include "base/os.h"
#include "base/unix_file/fd_file.h"
@@ -34,6 +33,7 @@
#include "dex/compact_dex_level.h"
// TODO: Add inl file and avoid including inl.
#include "obj_ptr-inl.h"
+#include "runtime_globals.h"
#include "scoped_thread_state_change-inl.h"
namespace art {
diff --git a/runtime/compiler_filter.cc b/runtime/compiler_filter.cc
index bda64eb..c086490 100644
--- a/runtime/compiler_filter.cc
+++ b/runtime/compiler_filter.cc
@@ -16,6 +16,8 @@
#include "compiler_filter.h"
+#include <ostream>
+
#include "base/utils.h"
namespace art {
diff --git a/runtime/compiler_filter.h b/runtime/compiler_filter.h
index 012ebcb..c36e40f 100644
--- a/runtime/compiler_filter.h
+++ b/runtime/compiler_filter.h
@@ -17,7 +17,7 @@
#ifndef ART_RUNTIME_COMPILER_FILTER_H_
#define ART_RUNTIME_COMPILER_FILTER_H_
-#include <ostream>
+#include <iosfwd>
#include <string>
#include <vector>
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index adf01c3..663af81 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -681,13 +681,13 @@
//
// The performance cost of this is non-negligible during native-debugging due to the
// forced JIT, so we keep the AOT code in that case in exchange for limited native debugging.
+ ScopedSuspendAll ssa(__FUNCTION__);
if (!runtime->IsJavaDebuggable() &&
!runtime->GetInstrumentation()->IsForcedInterpretOnly() &&
!runtime->IsNativeDebuggable()) {
runtime->DeoptimizeBootImage();
}
- ScopedSuspendAll ssa(__FUNCTION__);
if (RequiresDeoptimization()) {
runtime->GetInstrumentation()->EnableDeoptimization();
}
diff --git a/runtime/fault_handler.h b/runtime/fault_handler.h
index d3be51f..f6cf2d7 100644
--- a/runtime/fault_handler.h
+++ b/runtime/fault_handler.h
@@ -23,8 +23,8 @@
#include <vector>
-#include "base/globals.h" // For CanDoImplicitNullCheckOn.
#include "base/locks.h" // For annotalysis.
+#include "runtime_globals.h" // For CanDoImplicitNullCheckOn.
namespace art {
diff --git a/runtime/gc/accounting/bitmap.h b/runtime/gc/accounting/bitmap.h
index bdc686e..68f2d04 100644
--- a/runtime/gc/accounting/bitmap.h
+++ b/runtime/gc/accounting/bitmap.h
@@ -23,9 +23,9 @@
#include <set>
#include <vector>
-#include "base/globals.h"
#include "base/locks.h"
#include "base/mem_map.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/runtime/gc/accounting/card_table.h b/runtime/gc/accounting/card_table.h
index c99ed4b..30c4386 100644
--- a/runtime/gc/accounting/card_table.h
+++ b/runtime/gc/accounting/card_table.h
@@ -19,9 +19,9 @@
#include <memory>
-#include "base/globals.h"
#include "base/locks.h"
#include "base/mem_map.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/runtime/gc/accounting/mod_union_table.h b/runtime/gc/accounting/mod_union_table.h
index 8c471bc..011e95c 100644
--- a/runtime/gc/accounting/mod_union_table.h
+++ b/runtime/gc/accounting/mod_union_table.h
@@ -18,12 +18,12 @@
#define ART_RUNTIME_GC_ACCOUNTING_MOD_UNION_TABLE_H_
#include "base/allocator.h"
-#include "base/globals.h"
#include "base/safe_map.h"
#include "base/tracking_safe_map.h"
#include "bitmap.h"
#include "card_table.h"
#include "mirror/object_reference.h"
+#include "runtime_globals.h"
#include <set>
#include <vector>
diff --git a/runtime/gc/accounting/read_barrier_table.h b/runtime/gc/accounting/read_barrier_table.h
index 2e42f8d..44cdb5e 100644
--- a/runtime/gc/accounting/read_barrier_table.h
+++ b/runtime/gc/accounting/read_barrier_table.h
@@ -20,10 +20,10 @@
#include <sys/mman.h> // For the PROT_* and MAP_* constants.
#include "base/bit_utils.h"
-#include "base/globals.h"
#include "base/locks.h"
#include "base/mem_map.h"
#include "gc/space/space.h"
+#include "runtime_globals.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/accounting/remembered_set.h b/runtime/gc/accounting/remembered_set.h
index 469074f..3525667 100644
--- a/runtime/gc/accounting/remembered_set.h
+++ b/runtime/gc/accounting/remembered_set.h
@@ -18,9 +18,9 @@
#define ART_RUNTIME_GC_ACCOUNTING_REMEMBERED_SET_H_
#include "base/allocator.h"
-#include "base/globals.h"
#include "base/locks.h"
#include "base/safe_map.h"
+#include "runtime_globals.h"
#include <set>
#include <vector>
diff --git a/runtime/gc/accounting/space_bitmap.h b/runtime/gc/accounting/space_bitmap.h
index 8561f06..6ca254a 100644
--- a/runtime/gc/accounting/space_bitmap.h
+++ b/runtime/gc/accounting/space_bitmap.h
@@ -23,9 +23,9 @@
#include <set>
#include <vector>
-#include "base/globals.h"
#include "base/locks.h"
#include "base/mem_map.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/runtime/gc/accounting/space_bitmap_test.cc b/runtime/gc/accounting/space_bitmap_test.cc
index 22529b8..9f355e3 100644
--- a/runtime/gc/accounting/space_bitmap_test.cc
+++ b/runtime/gc/accounting/space_bitmap_test.cc
@@ -19,9 +19,9 @@
#include <stdint.h>
#include <memory>
-#include "base/globals.h"
#include "base/mutex.h"
#include "common_runtime_test.h"
+#include "runtime_globals.h"
#include "space_bitmap-inl.h"
namespace art {
diff --git a/runtime/gc/allocator/dlmalloc.cc b/runtime/gc/allocator/dlmalloc.cc
index 11ad8a8..79d4fbf 100644
--- a/runtime/gc/allocator/dlmalloc.cc
+++ b/runtime/gc/allocator/dlmalloc.cc
@@ -60,8 +60,8 @@
#include <sys/mman.h>
-#include "base/globals.h"
#include "base/utils.h"
+#include "runtime_globals.h"
extern "C" void DlmallocMadviseCallback(void* start, void* end, size_t used_bytes, void* arg) {
// Is this chunk in use?
diff --git a/runtime/gc/allocator/rosalloc.h b/runtime/gc/allocator/rosalloc.h
index bf26aea..0906295 100644
--- a/runtime/gc/allocator/rosalloc.h
+++ b/runtime/gc/allocator/rosalloc.h
@@ -30,9 +30,9 @@
#include "base/allocator.h"
#include "base/bit_utils.h"
-#include "base/globals.h"
#include "base/mem_map.h"
#include "base/mutex.h"
+#include "runtime_globals.h"
#include "thread.h"
namespace art {
diff --git a/runtime/gc/gc_cause.cc b/runtime/gc/gc_cause.cc
index ee7ac7d..8b4bac2 100644
--- a/runtime/gc/gc_cause.cc
+++ b/runtime/gc/gc_cause.cc
@@ -18,8 +18,8 @@
#include <android-base/logging.h>
-#include "base/globals.h"
#include "base/macros.h"
+#include "runtime_globals.h"
#include <ostream>
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 9949bf4..341f16a 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -25,9 +25,7 @@
#include <android-base/logging.h>
#include "allocator_type.h"
-#include "arch/instruction_set.h"
#include "base/atomic.h"
-#include "base/globals.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "base/runtime_debug.h"
@@ -43,11 +41,13 @@
#include "offsets.h"
#include "process_state.h"
#include "read_barrier_config.h"
+#include "runtime_globals.h"
#include "verify_object.h"
namespace art {
class ConditionVariable;
+enum class InstructionSet;
class IsMarkedVisitor;
class Mutex;
class RootVisitor;
diff --git a/runtime/gc/reference_processor.h b/runtime/gc/reference_processor.h
index 17b546a..c1c9a3c 100644
--- a/runtime/gc/reference_processor.h
+++ b/runtime/gc/reference_processor.h
@@ -17,10 +17,10 @@
#ifndef ART_RUNTIME_GC_REFERENCE_PROCESSOR_H_
#define ART_RUNTIME_GC_REFERENCE_PROCESSOR_H_
-#include "base/globals.h"
#include "base/locks.h"
#include "jni.h"
#include "reference_queue.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/runtime/gc/reference_queue.h b/runtime/gc/reference_queue.h
index 53518cc..90f0be7 100644
--- a/runtime/gc/reference_queue.h
+++ b/runtime/gc/reference_queue.h
@@ -22,12 +22,12 @@
#include <vector>
#include "base/atomic.h"
-#include "base/globals.h"
#include "base/locks.h"
#include "base/timing_logger.h"
#include "jni.h"
#include "obj_ptr.h"
#include "offsets.h"
+#include "runtime_globals.h"
#include "thread_pool.h"
namespace art {
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 64fd3cd..5ad5f52 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -25,6 +25,7 @@
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
+#include "arch/instruction_set.h"
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/array_ref.h"
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index 14e364a..42ac3e2 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -17,7 +17,6 @@
#ifndef ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_
#define ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_
-#include "arch/instruction_set.h"
#include "gc/accounting/space_bitmap.h"
#include "image.h"
#include "space.h"
@@ -26,6 +25,7 @@
template <typename T> class ArrayRef;
class DexFile;
+enum class InstructionSet;
class OatFile;
namespace gc {
diff --git a/runtime/gc/space/image_space_fs.h b/runtime/gc/space/image_space_fs.h
index 14deb6f..262c6e0 100644
--- a/runtime/gc/space/image_space_fs.h
+++ b/runtime/gc/space/image_space_fs.h
@@ -23,13 +23,13 @@
#include "android-base/stringprintf.h"
#include "base/file_utils.h"
-#include "base/globals.h"
#include "base/logging.h" // For VLOG.
#include "base/macros.h"
#include "base/os.h"
#include "base/unix_file/fd_file.h"
#include "base/utils.h"
#include "runtime.h"
+#include "runtime_globals.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/space/malloc_space.cc b/runtime/gc/space/malloc_space.cc
index b5e6b62..474231b 100644
--- a/runtime/gc/space/malloc_space.cc
+++ b/runtime/gc/space/malloc_space.cc
@@ -16,6 +16,8 @@
#include "malloc_space.h"
+#include <ostream>
+
#include "android-base/stringprintf.h"
#include "base/logging.h" // For VLOG
diff --git a/runtime/gc/space/malloc_space.h b/runtime/gc/space/malloc_space.h
index 7d28516..9a90dfd 100644
--- a/runtime/gc/space/malloc_space.h
+++ b/runtime/gc/space/malloc_space.h
@@ -19,7 +19,8 @@
#include "space.h"
-#include <ostream>
+#include <iosfwd>
+
#include "base/memory_tool.h"
#include "base/mutex.h"
diff --git a/runtime/gc/space/space.h b/runtime/gc/space/space.h
index dd5451b..903263f 100644
--- a/runtime/gc/space/space.h
+++ b/runtime/gc/space/space.h
@@ -21,12 +21,12 @@
#include <string>
#include "base/atomic.h"
-#include "base/globals.h"
#include "base/locks.h"
#include "base/macros.h"
#include "base/mem_map.h"
#include "gc/accounting/space_bitmap.h"
#include "gc/collector/object_byte_pair.h"
+#include "runtime_globals.h"
namespace art {
namespace mirror {
diff --git a/runtime/gc/space/space_test.h b/runtime/gc/space/space_test.h
index 1b111e3..7fbd0b5 100644
--- a/runtime/gc/space/space_test.h
+++ b/runtime/gc/space/space_test.h
@@ -20,13 +20,13 @@
#include <stdint.h>
#include <memory>
-#include "base/globals.h"
#include "common_runtime_test.h"
#include "handle_scope-inl.h"
#include "mirror/array-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "mirror/object-inl.h"
+#include "runtime_globals.h"
#include "scoped_thread_state_change-inl.h"
#include "thread_list.h"
#include "zygote_space.h"
diff --git a/runtime/gc/task_processor.h b/runtime/gc/task_processor.h
index 6db3c37..86e36ab 100644
--- a/runtime/gc/task_processor.h
+++ b/runtime/gc/task_processor.h
@@ -20,8 +20,8 @@
#include <memory>
#include <set>
-#include "base/globals.h"
#include "base/mutex.h"
+#include "runtime_globals.h"
#include "thread_pool.h"
namespace art {
diff --git a/runtime/handle_scope-inl.h b/runtime/handle_scope-inl.h
index f61c700..765ed7d 100644
--- a/runtime/handle_scope-inl.h
+++ b/runtime/handle_scope-inl.h
@@ -21,6 +21,7 @@
#include "base/mutex.h"
#include "handle.h"
+#include "handle_wrapper.h"
#include "obj_ptr-inl.h"
#include "thread-current-inl.h"
#include "verify_object.h"
@@ -106,6 +107,15 @@
handle_scope_entry <= &GetReferences()[number_of_references_ - 1];
}
+template <typename Visitor>
+inline void HandleScope::VisitRoots(Visitor& visitor) {
+ for (size_t i = 0, count = NumberOfReferences(); i < count; ++i) {
+ // GetReference returns a pointer to the stack reference within the handle scope. If this
+ // needs to be updated, it will be done by the root visitor.
+ visitor.VisitRootIfNonNull(GetHandle(i).GetReference());
+ }
+}
+
template<size_t kNumReferences> template<class T>
inline MutableHandle<T> FixedSizeHandleScope<kNumReferences>::NewHandle(T* object) {
SetReference(pos_, object);
diff --git a/runtime/handle_scope.h b/runtime/handle_scope.h
index 1a1c92f..dae8e29 100644
--- a/runtime/handle_scope.h
+++ b/runtime/handle_scope.h
@@ -24,13 +24,16 @@
#include "base/enums.h"
#include "base/locks.h"
#include "base/macros.h"
-#include "handle.h"
#include "stack_reference.h"
#include "verify_object.h"
namespace art {
+template<class T> class Handle;
class HandleScope;
+template<class T> class HandleWrapper;
+template<class T> class HandleWrapperObjPtr;
+template<class T> class MutableHandle;
template<class MirrorType> class ObjPtr;
class Thread;
class VariableSizedHandleScope;
@@ -144,13 +147,7 @@
}
template <typename Visitor>
- void VisitRoots(Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_) {
- for (size_t i = 0, count = NumberOfReferences(); i < count; ++i) {
- // GetReference returns a pointer to the stack reference within the handle scope. If this
- // needs to be updated, it will be done by the root visitor.
- visitor.VisitRootIfNonNull(GetHandle(i).GetReference());
- }
- }
+ ALWAYS_INLINE void VisitRoots(Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_);
protected:
// Return backing storage used for references.
@@ -172,44 +169,6 @@
DISALLOW_COPY_AND_ASSIGN(HandleScope);
};
-// A wrapper which wraps around Object** and restores the pointer in the destructor.
-// TODO: Delete
-template<class T>
-class HandleWrapper : public MutableHandle<T> {
- public:
- HandleWrapper(T** obj, const MutableHandle<T>& handle)
- : MutableHandle<T>(handle), obj_(obj) {
- }
-
- HandleWrapper(const HandleWrapper&) = default;
-
- ~HandleWrapper() {
- *obj_ = MutableHandle<T>::Get();
- }
-
- private:
- T** const obj_;
-};
-
-
-// A wrapper which wraps around ObjPtr<Object>* and restores the pointer in the destructor.
-// TODO: Add more functionality.
-template<class T>
-class HandleWrapperObjPtr : public MutableHandle<T> {
- public:
- HandleWrapperObjPtr(ObjPtr<T>* obj, const MutableHandle<T>& handle)
- : MutableHandle<T>(handle), obj_(obj) {}
-
- HandleWrapperObjPtr(const HandleWrapperObjPtr&) = default;
-
- ~HandleWrapperObjPtr() {
- *obj_ = ObjPtr<T>(MutableHandle<T>::Get());
- }
-
- private:
- ObjPtr<T>* const obj_;
-};
-
// Fixed size handle scope that is not necessarily linked in the thread.
template<size_t kNumReferences>
class PACKED(4) FixedSizeHandleScope : public HandleScope {
diff --git a/runtime/handle_wrapper.h b/runtime/handle_wrapper.h
new file mode 100644
index 0000000..01252c7
--- /dev/null
+++ b/runtime/handle_wrapper.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 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_HANDLE_WRAPPER_H_
+#define ART_RUNTIME_HANDLE_WRAPPER_H_
+
+#include "handle.h"
+#include "obj_ptr.h"
+
+namespace art {
+
+// A wrapper which wraps around Object** and restores the pointer in the destructor.
+// TODO: Delete
+template<class T>
+class HandleWrapper : public MutableHandle<T> {
+ public:
+ HandleWrapper(T** obj, const MutableHandle<T>& handle)
+ : MutableHandle<T>(handle), obj_(obj) {
+ }
+
+ HandleWrapper(const HandleWrapper&) = default;
+
+ ~HandleWrapper() {
+ *obj_ = MutableHandle<T>::Get();
+ }
+
+ private:
+ T** const obj_;
+};
+
+
+// A wrapper which wraps around ObjPtr<Object>* and restores the pointer in the destructor.
+// TODO: Add more functionality.
+template<class T>
+class HandleWrapperObjPtr : public MutableHandle<T> {
+ public:
+ HandleWrapperObjPtr(ObjPtr<T>* obj, const MutableHandle<T>& handle)
+ : MutableHandle<T>(handle), obj_(obj) {}
+
+ HandleWrapperObjPtr(const HandleWrapperObjPtr&) = default;
+
+ ~HandleWrapperObjPtr() {
+ *obj_ = ObjPtr<T>(MutableHandle<T>::Get());
+ }
+
+ private:
+ ObjPtr<T>* const obj_;
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_HANDLE_WRAPPER_H_
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index 3abe4c5..34f645b 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -42,7 +42,6 @@
#include "art_method-inl.h"
#include "base/array_ref.h"
#include "base/file_utils.h"
-#include "base/globals.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "base/os.h"
@@ -66,6 +65,7 @@
#include "mirror/class-inl.h"
#include "mirror/class.h"
#include "mirror/object-refvisitor-inl.h"
+#include "runtime_globals.h"
#include "scoped_thread_state_change-inl.h"
#include "thread_list.h"
diff --git a/runtime/image.h b/runtime/image.h
index 140f504..6578287 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -20,9 +20,9 @@
#include <string.h>
#include "base/enums.h"
-#include "base/globals.h"
#include "base/iteration_range.h"
#include "mirror/object.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 27c47bc..36f7b3d 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -848,7 +848,7 @@
new_quick_code = GetQuickInstrumentationEntryPoint();
if (!method->IsNative() && Runtime::Current()->GetJit() != nullptr) {
// Native methods use trampoline entrypoints during interpreter tracing.
- DCHECK(!Runtime::Current()->GetJit()->GetCodeCache()->GetGarbageCollectCode());
+ DCHECK(!Runtime::Current()->GetJit()->GetCodeCache()->GetGarbageCollectCodeUnsafe());
ProfilingInfo* profiling_info = method->GetProfilingInfo(kRuntimePointerSize);
// Tracing will look at the saved entry point in the profiling info to know the actual
// entrypoint, so we store it here.
@@ -1050,14 +1050,6 @@
level = InstrumentationLevel::kInstrumentWithInterpreter;
} else {
level = InstrumentationLevel::kInstrumentWithInstrumentationStubs;
- if (Runtime::Current()->GetJit() != nullptr) {
- // TODO b/110263880 It would be better if we didn't need to do this.
- // Since we need to hold the method entrypoint across a suspend to ensure instrumentation
- // hooks are called correctly we have to disable jit-gc to ensure that the entrypoint doesn't
- // go away. Furthermore we need to leave this off permanently since one could get the same
- // effect by causing this to be toggled on and off.
- Runtime::Current()->GetJit()->GetCodeCache()->SetGarbageCollectCode(false);
- }
}
ConfigureStubs(key, level);
}
diff --git a/runtime/jdwp_provider.h b/runtime/jdwp_provider.h
index 9579513..29fbc3f 100644
--- a/runtime/jdwp_provider.h
+++ b/runtime/jdwp_provider.h
@@ -19,7 +19,7 @@
#include <ios>
-#include "base/globals.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index d976fec..c1b9a1a 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -390,7 +390,7 @@
// Zygote should never collect code to share the memory with the children.
if (is_zygote) {
- jit_code_cache->SetGarbageCollectCode(false);
+ jit_code_cache->garbage_collect_code_ = false;
}
if (!jit_code_cache->InitializeMappings(rwx_memory_allowed, is_zygote, error_msg)) {
@@ -1247,6 +1247,24 @@
}
}
+void JitCodeCache::ClearEntryPointsInZygoteExecSpace() {
+ MutexLock mu(Thread::Current(), lock_);
+ // Iterate over profiling infos to know which methods may have been JITted. Note that
+ // to be JITted, a method must have a profiling info.
+ for (ProfilingInfo* info : profiling_infos_) {
+ ArtMethod* method = info->GetMethod();
+ if (IsInZygoteExecSpace(method->GetEntryPointFromQuickCompiledCode())) {
+ method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+ }
+ // If zygote does method tracing, or in some configuration where
+ // the JIT zygote does GC, we also need to clear the saved entry point
+ // in the profiling info.
+ if (IsInZygoteExecSpace(info->GetSavedEntryPoint())) {
+ info->SetSavedEntryPoint(nullptr);
+ }
+ }
+}
+
size_t JitCodeCache::CodeCacheSizeLocked() {
return used_memory_for_code_;
}
@@ -1437,17 +1455,14 @@
void JitCodeCache::GarbageCollectCache(Thread* self) {
ScopedTrace trace(__FUNCTION__);
- if (!garbage_collect_code_) {
- MutexLock mu(self, lock_);
- IncreaseCodeCacheCapacity();
- return;
- }
-
// Wait for an existing collection, or let everyone know we are starting one.
{
ScopedThreadSuspension sts(self, kSuspended);
MutexLock mu(self, lock_);
- if (WaitForPotentialCollectionToComplete(self)) {
+ if (!garbage_collect_code_) {
+ IncreaseCodeCacheCapacity();
+ return;
+ } else if (WaitForPotentialCollectionToComplete(self)) {
return;
} else {
number_of_collections_++;
@@ -1573,6 +1588,29 @@
FreeAllMethodHeaders(method_headers);
}
+bool JitCodeCache::GetGarbageCollectCode() {
+ MutexLock mu(Thread::Current(), lock_);
+ return garbage_collect_code_;
+}
+
+void JitCodeCache::SetGarbageCollectCode(bool value) {
+ Thread* self = Thread::Current();
+ MutexLock mu(self, lock_);
+ if (garbage_collect_code_ != value) {
+ if (garbage_collect_code_) {
+ // When dynamically disabling the garbage collection, we neee
+ // to make sure that a potential current collection is finished, and also
+ // clear the saved entry point in profiling infos to avoid dangling pointers.
+ WaitForPotentialCollectionToComplete(self);
+ for (ProfilingInfo* info : profiling_infos_) {
+ info->SetSavedEntryPoint(nullptr);
+ }
+ }
+ // Update the flag while holding the lock to ensure no thread will try to GC.
+ garbage_collect_code_ = value;
+ }
+}
+
void JitCodeCache::DoCollection(Thread* self, bool collect_profiling_info) {
ScopedTrace trace(__FUNCTION__);
{
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index e2f3357..8a6cebe 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -246,13 +246,13 @@
void MoveObsoleteMethod(ArtMethod* old_method, ArtMethod* new_method)
REQUIRES(!lock_) REQUIRES(Locks::mutator_lock_);
- // Dynamically change whether we want to garbage collect code. Should only be used during JIT
- // initialization or by tests.
- void SetGarbageCollectCode(bool value) {
- garbage_collect_code_ = value;
- }
+ // Dynamically change whether we want to garbage collect code.
+ void SetGarbageCollectCode(bool value) REQUIRES(!lock_);
- bool GetGarbageCollectCode() const {
+ bool GetGarbageCollectCode() REQUIRES(!lock_);
+
+ // Unsafe variant for debug checks.
+ bool GetGarbageCollectCodeUnsafe() const NO_THREAD_SAFETY_ANALYSIS {
return garbage_collect_code_;
}
@@ -264,6 +264,11 @@
void PostForkChildAction(bool is_system_server, bool is_zygote);
+ // Clear the entrypoints of JIT compiled methods that belong in the zygote space.
+ // This is used for removing non-debuggable JIT code at the point we realize the runtime
+ // is debuggable.
+ void ClearEntryPointsInZygoteExecSpace() REQUIRES(!lock_) REQUIRES(Locks::mutator_lock_);
+
private:
JitCodeCache();
@@ -451,7 +456,7 @@
bool last_collection_increased_code_cache_ GUARDED_BY(lock_);
// Whether we can do garbage collection. Not 'const' as tests may override this.
- bool garbage_collect_code_;
+ bool garbage_collect_code_ GUARDED_BY(lock_);
// The size in bytes of used memory for the data portion of the code cache.
size_t used_memory_for_data_ GUARDED_BY(lock_);
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 40c7d30..fe49813 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -39,6 +39,7 @@
#include "runtime.h"
#include "string.h"
#include "subtype_check.h"
+#include "thread-current-inl.h"
namespace art {
namespace mirror {
@@ -1117,6 +1118,18 @@
}
}
+inline void Class::SetRecursivelyInitialized() {
+ DCHECK_EQ(GetLockOwnerThreadId(), Thread::Current()->GetThreadId());
+ uint32_t flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
+ SetAccessFlags(flags | kAccRecursivelyInitialized);
+}
+
+inline void Class::SetHasDefaultMethods() {
+ DCHECK_EQ(GetLockOwnerThreadId(), Thread::Current()->GetThreadId());
+ uint32_t flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
+ SetAccessFlags(flags | kAccHasDefaultMethod);
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index f7a41f7..d35d526 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -30,7 +30,6 @@
#include "object.h"
#include "object_array.h"
#include "read_barrier_option.h"
-#include "thread-current-inl.h"
namespace art {
@@ -52,6 +51,7 @@
class Signature;
class StringPiece;
template<size_t kNumReferences> class PACKED(4) StackHandleScope;
+class Thread;
namespace mirror {
@@ -223,17 +223,9 @@
SetAccessFlags(flags | kAccSkipHiddenapiChecks);
}
- ALWAYS_INLINE void SetRecursivelyInitialized() REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK_EQ(GetLockOwnerThreadId(), Thread::Current()->GetThreadId());
- uint32_t flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
- SetAccessFlags(flags | kAccRecursivelyInitialized);
- }
+ ALWAYS_INLINE void SetRecursivelyInitialized() REQUIRES_SHARED(Locks::mutator_lock_);
- ALWAYS_INLINE void SetHasDefaultMethods() REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK_EQ(GetLockOwnerThreadId(), Thread::Current()->GetThreadId());
- uint32_t flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
- SetAccessFlags(flags | kAccHasDefaultMethod);
- }
+ ALWAYS_INLINE void SetHasDefaultMethods() REQUIRES_SHARED(Locks::mutator_lock_);
ALWAYS_INLINE void SetFinalizable() REQUIRES_SHARED(Locks::mutator_lock_) {
uint32_t flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc
index 8d2b838..7e79ebe 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -17,7 +17,6 @@
#include "dex_cache-inl.h"
#include "art_method-inl.h"
-#include "base/globals.h"
#include "class_linker.h"
#include "gc/accounting/card_table-inl.h"
#include "gc/heap.h"
@@ -27,6 +26,7 @@
#include "object.h"
#include "object_array-inl.h"
#include "runtime.h"
+#include "runtime_globals.h"
#include "string.h"
#include "thread.h"
#include "utils/dex_cache_arrays_layout-inl.h"
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index bca7511..ba222f6 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -20,13 +20,13 @@
#include "base/atomic.h"
#include "base/casts.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "dex/primitive.h"
#include "obj_ptr.h"
#include "object_reference.h"
#include "offsets.h"
#include "read_barrier_config.h"
#include "read_barrier_option.h"
+#include "runtime_globals.h"
#include "verify_object.h"
namespace art {
diff --git a/runtime/mirror/object_reference.h b/runtime/mirror/object_reference.h
index 8636928..e19e165 100644
--- a/runtime/mirror/object_reference.h
+++ b/runtime/mirror/object_reference.h
@@ -18,10 +18,10 @@
#define ART_RUNTIME_MIRROR_OBJECT_REFERENCE_H_
#include "base/atomic.h"
-#include "base/globals.h"
#include "base/locks.h" // For Locks::mutator_lock_.
#include "heap_poisoning.h"
#include "obj_ptr.h"
+#include "runtime_globals.h"
namespace art {
namespace mirror {
diff --git a/runtime/mirror/string-alloc-inl.h b/runtime/mirror/string-alloc-inl.h
index c31eccf..4c4e2af 100644
--- a/runtime/mirror/string-alloc-inl.h
+++ b/runtime/mirror/string-alloc-inl.h
@@ -22,11 +22,11 @@
#include "array.h"
#include "base/bit_utils.h"
-#include "base/globals.h"
#include "class.h"
#include "class_root.h"
#include "gc/heap-inl.h"
#include "runtime.h"
+#include "runtime_globals.h"
#include "thread.h"
namespace art {
diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h
index e11906a..f04a8aa 100644
--- a/runtime/mirror/string-inl.h
+++ b/runtime/mirror/string-inl.h
@@ -20,10 +20,10 @@
#include "android-base/stringprintf.h"
-#include "base/globals.h"
#include "class-inl.h"
#include "common_throws.h"
#include "dex/utf.h"
+#include "runtime_globals.h"
namespace art {
namespace mirror {
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index b32db08..c367957 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -18,10 +18,10 @@
#define ART_RUNTIME_MIRROR_STRING_H_
#include "base/bit_utils.h"
-#include "base/globals.h"
#include "gc/allocator_type.h"
#include "class.h"
#include "object.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 9ce4749..26fc5e9 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -203,8 +203,11 @@
runtime->AddCompilerOption("--debuggable");
runtime_flags |= DEBUG_GENERATE_MINI_DEBUG_INFO;
runtime->SetJavaDebuggable(true);
- // Deoptimize the boot image as it may be non-debuggable.
- runtime->DeoptimizeBootImage();
+ {
+ // Deoptimize the boot image as it may be non-debuggable.
+ ScopedSuspendAll ssa(__FUNCTION__);
+ runtime->DeoptimizeBootImage();
+ }
runtime_flags &= ~DEBUG_JAVA_DEBUGGABLE;
needs_non_debuggable_classes = true;
}
diff --git a/runtime/oat.cc b/runtime/oat.cc
index d7c968f..c6a963a 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -20,6 +20,7 @@
#include "android-base/stringprintf.h"
+#include "arch/instruction_set.h"
#include "arch/instruction_set_features.h"
#include "base/bit_utils.h"
#include "base/strlcpy.h"
diff --git a/runtime/oat.h b/runtime/oat.h
index ded1489..88238d9 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -19,13 +19,13 @@
#include <vector>
-#include "arch/instruction_set.h"
#include "base/macros.h"
#include "base/safe_map.h"
#include "compiler_filter.h"
namespace art {
+enum class InstructionSet;
class InstructionSetFeatures;
class PACKED(4) OatHeader {
diff --git a/runtime/obj_ptr-inl.h b/runtime/obj_ptr-inl.h
index b949c96..f096445 100644
--- a/runtime/obj_ptr-inl.h
+++ b/runtime/obj_ptr-inl.h
@@ -17,6 +17,8 @@
#ifndef ART_RUNTIME_OBJ_PTR_INL_H_
#define ART_RUNTIME_OBJ_PTR_INL_H_
+#include <ostream>
+
#include "base/bit_utils.h"
#include "obj_ptr.h"
#include "thread-current-inl.h"
diff --git a/runtime/obj_ptr.h b/runtime/obj_ptr.h
index 9e2ee29..b0f24da 100644
--- a/runtime/obj_ptr.h
+++ b/runtime/obj_ptr.h
@@ -17,12 +17,12 @@
#ifndef ART_RUNTIME_OBJ_PTR_H_
#define ART_RUNTIME_OBJ_PTR_H_
-#include <ostream>
+#include <iosfwd>
#include <type_traits>
-#include "base/globals.h"
#include "base/locks.h" // For Locks::mutator_lock_.
#include "base/macros.h"
+#include "runtime_globals.h"
// Always inline ObjPtr methods even in debug builds.
#define OBJPTR_INLINE __attribute__ ((always_inline))
diff --git a/runtime/offsets.h b/runtime/offsets.h
index 372b821..6d1a8e0 100644
--- a/runtime/offsets.h
+++ b/runtime/offsets.h
@@ -17,10 +17,10 @@
#ifndef ART_RUNTIME_OFFSETS_H_
#define ART_RUNTIME_OFFSETS_H_
-#include <ostream>
+#include <iosfwd>
#include "base/enums.h"
-#include "base/globals.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h
index 8c77d39..095d66e 100644
--- a/runtime/parsed_options.h
+++ b/runtime/parsed_options.h
@@ -23,10 +23,10 @@
#include <jni.h>
#include "arch/instruction_set.h"
-#include "base/globals.h"
#include "gc/collector_type.h"
#include "gc/space/large_object_space.h"
// #include "jit/profile_saver_options.h"
+#include "runtime_globals.h"
#include "runtime_options.h"
namespace art {
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index dfd7e64..dbf40f6a 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -33,6 +33,7 @@
#include "nth_caller_visitor.h"
#include "scoped_thread_state_change-inl.h"
#include "stack_reference.h"
+#include "thread-inl.h"
#include "well_known_classes.h"
namespace art {
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index f30ba0c..eea7c67 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -42,6 +42,7 @@
#include "aot_class_linker.h"
#include "arch/arm/registers_arm.h"
#include "arch/arm64/registers_arm64.h"
+#include "arch/context.h"
#include "arch/instruction_set_features.h"
#include "arch/mips/registers_mips.h"
#include "arch/mips64/registers_mips64.h"
@@ -1472,6 +1473,8 @@
if (IsJavaDebuggable()) {
// Now that we have loaded the boot image, deoptimize its methods if we are running
// debuggable, as the code may have been compiled non-debuggable.
+ ScopedThreadSuspension sts(self, ThreadState::kNative);
+ ScopedSuspendAll ssa(__FUNCTION__);
DeoptimizeBootImage();
}
} else {
@@ -1571,10 +1574,14 @@
// Runtime initialization is largely done now.
// We load plugins first since that can modify the runtime state slightly.
// Load all plugins
- for (auto& plugin : plugins_) {
- std::string err;
- if (!plugin.Load(&err)) {
- LOG(FATAL) << plugin << " failed to load: " << err;
+ {
+ // The init method of plugins expect the state of the thread to be non runnable.
+ ScopedThreadSuspension sts(self, ThreadState::kNative);
+ for (auto& plugin : plugins_) {
+ std::string err;
+ if (!plugin.Load(&err)) {
+ LOG(FATAL) << plugin << " failed to load: " << err;
+ }
}
}
@@ -2647,6 +2654,7 @@
: instrumentation_(instrumentation) {}
bool operator()(ObjPtr<mirror::Class> klass) override REQUIRES(Locks::mutator_lock_) {
+ DCHECK(Locks::mutator_lock_->IsExclusiveHeld(Thread::Current()));
auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
for (auto& m : klass->GetMethods(pointer_size)) {
const void* code = m.GetEntryPointFromQuickCompiledCode();
@@ -2673,9 +2681,13 @@
// we patch entry points of methods in boot image to interpreter bridge, as
// boot image code may be AOT compiled as not debuggable.
if (!GetInstrumentation()->IsForcedInterpretOnly()) {
- ScopedObjectAccess soa(Thread::Current());
UpdateEntryPointsClassVisitor visitor(GetInstrumentation());
GetClassLinker()->VisitClasses(&visitor);
+ jit::Jit* jit = GetJit();
+ if (jit != nullptr) {
+ // Code JITted by the zygote is not compiled debuggable.
+ jit->GetCodeCache()->ClearEntryPointsInZygoteExecSpace();
+ }
}
}
diff --git a/runtime/runtime.h b/runtime/runtime.h
index a2d519d..1acb75b 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -27,7 +27,6 @@
#include <memory>
#include <vector>
-#include "arch/instruction_set.h"
#include "base/locks.h"
#include "base/macros.h"
#include "base/mem_map.h"
@@ -84,6 +83,7 @@
class ClassLinker;
class CompilerCallbacks;
class DexFile;
+enum class InstructionSet;
class InternTable;
class IsMarkedVisitor;
class JavaVMExt;
@@ -634,7 +634,7 @@
void SetJavaDebuggable(bool value);
// Deoptimize the boot image, called for Java debuggable apps.
- void DeoptimizeBootImage();
+ void DeoptimizeBootImage() REQUIRES(Locks::mutator_lock_);
bool IsNativeDebuggable() const {
return is_native_debuggable_;
diff --git a/runtime/runtime_globals.h b/runtime/runtime_globals.h
new file mode 100644
index 0000000..793291a
--- /dev/null
+++ b/runtime/runtime_globals.h
@@ -0,0 +1,82 @@
+/*
+ * 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_RUNTIME_GLOBALS_H_
+#define ART_RUNTIME_RUNTIME_GLOBALS_H_
+
+#include "base/globals.h"
+
+namespace art {
+
+// Size of Dex virtual registers.
+static constexpr size_t kVRegSize = 4;
+
+// Returns whether the given memory offset can be used for generating
+// an implicit null check.
+static inline bool CanDoImplicitNullCheckOn(uintptr_t offset) {
+ return offset < kPageSize;
+}
+
+// Required object alignment
+static constexpr size_t kObjectAlignmentShift = 3;
+static constexpr size_t kObjectAlignment = 1u << kObjectAlignmentShift;
+static constexpr size_t kLargeObjectAlignment = kPageSize;
+
+// Garbage collector constants.
+static constexpr bool kMovingCollector = true;
+static constexpr bool kMarkCompactSupport = false && kMovingCollector;
+// True if we allow moving classes.
+static constexpr bool kMovingClasses = !kMarkCompactSupport;
+// If true, enable generational collection when using the Concurrent Copying
+// (CC) collector, i.e. use sticky-bit CC for minor collections and (full) CC
+// for major collections.
+//
+// Generational CC collection is currently only compatible with Baker read
+// barriers.
+#if defined(ART_USE_GENERATIONAL_CC) && defined(ART_READ_BARRIER_TYPE_IS_BAKER)
+static constexpr bool kEnableGenerationalConcurrentCopyingCollection = true;
+#else
+static constexpr bool kEnableGenerationalConcurrentCopyingCollection = false;
+#endif
+
+// If true, enable the tlab allocator by default.
+#ifdef ART_USE_TLAB
+static constexpr bool kUseTlab = true;
+#else
+static constexpr bool kUseTlab = false;
+#endif
+
+// Kinds of tracing clocks.
+enum class TraceClockSource {
+ kThreadCpu,
+ kWall,
+ kDual, // Both wall and thread CPU clocks.
+};
+
+#if defined(__linux__)
+static constexpr TraceClockSource kDefaultTraceClockSource = TraceClockSource::kDual;
+#else
+static constexpr TraceClockSource kDefaultTraceClockSource = TraceClockSource::kWall;
+#endif
+
+static constexpr bool kDefaultMustRelocate = true;
+
+// Size of a heap reference.
+static constexpr size_t kHeapReferenceSize = sizeof(uint32_t);
+
+} // namespace art
+
+#endif // ART_RUNTIME_RUNTIME_GLOBALS_H_
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 25939d2..9a677de 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -568,7 +568,9 @@
cur_shadow_frame_->SetMethod(method);
} else {
DCHECK(cur_quick_frame_ != nullptr);
- CHECK(!IsInInlinedFrame()) << "We do not support setting inlined method's ArtMethod!";
+ CHECK(!IsInInlinedFrame()) << "We do not support setting inlined method's ArtMethod: "
+ << GetMethod()->PrettyMethod() << " is inlined into "
+ << GetOuterMethod()->PrettyMethod();
*cur_quick_frame_ = method;
}
}
diff --git a/runtime/suspend_reason.h b/runtime/suspend_reason.h
index 289a1a4..af2be10 100644
--- a/runtime/suspend_reason.h
+++ b/runtime/suspend_reason.h
@@ -17,7 +17,7 @@
#ifndef ART_RUNTIME_SUSPEND_REASON_H_
#define ART_RUNTIME_SUSPEND_REASON_H_
-#include <ostream>
+#include <iosfwd>
namespace art {
diff --git a/runtime/thread-inl.h b/runtime/thread-inl.h
index 0c00fb9..00f882e 100644
--- a/runtime/thread-inl.h
+++ b/runtime/thread-inl.h
@@ -19,6 +19,7 @@
#include "thread.h"
+#include "arch/instruction_set.h"
#include "base/aborting.h"
#include "base/casts.h"
#include "base/mutex-inl.h"
@@ -393,6 +394,26 @@
return tlsPtr_.managed_stack.PopShadowFrame();
}
+inline uint8_t* Thread::GetStackEndForInterpreter(bool implicit_overflow_check) const {
+ uint8_t* end = tlsPtr_.stack_end + (implicit_overflow_check
+ ? GetStackOverflowReservedBytes(kRuntimeISA)
+ : 0);
+ if (kIsDebugBuild) {
+ // In a debuggable build, but especially under ASAN, the access-checks interpreter has a
+ // potentially humongous stack size. We don't want to take too much of the stack regularly,
+ // so do not increase the regular reserved size (for compiled code etc) and only report the
+ // virtually smaller stack to the interpreter here.
+ end += GetStackOverflowReservedBytes(kRuntimeISA);
+ }
+ return end;
+}
+
+inline void Thread::ResetDefaultStackEnd() {
+ // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room
+ // to throw a StackOverflowError.
+ tlsPtr_.stack_end = tlsPtr_.stack_begin + GetStackOverflowReservedBytes(kRuntimeISA);
+}
+
} // namespace art
#endif // ART_RUNTIME_THREAD_INL_H_
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 7c050a4..309c04e 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -48,6 +48,7 @@
#include "base/atomic.h"
#include "base/bit_utils.h"
#include "base/casts.h"
+#include "arch/context.h"
#include "base/file_utils.h"
#include "base/memory_tool.h"
#include "base/mutex.h"
@@ -4232,4 +4233,17 @@
Runtime::Current()->GetThreadList()->RunCheckpoint(&closure);
}
+void Thread::ReleaseLongJumpContextInternal() {
+ // Each QuickExceptionHandler gets a long jump context and uses
+ // it for doing the long jump, after finding catch blocks/doing deoptimization.
+ // Both finding catch blocks and deoptimization can trigger another
+ // exception such as a result of class loading. So there can be nested
+ // cases of exception handling and multiple contexts being used.
+ // ReleaseLongJumpContext tries to save the context in tlsPtr_.long_jump_context
+ // for reuse so there is no need to always allocate a new one each time when
+ // getting a context. Since we only keep one context for reuse, delete the
+ // existing one since the passed in context is yet to be used for longjump.
+ delete tlsPtr_.long_jump_context;
+}
+
} // namespace art
diff --git a/runtime/thread.h b/runtime/thread.h
index ad69ecf..7a14fd7 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -25,14 +25,12 @@
#include <memory>
#include <string>
-#include "arch/context.h"
-#include "arch/instruction_set.h"
#include "base/atomic.h"
#include "base/enums.h"
-#include "base/globals.h"
#include "base/locks.h"
#include "base/macros.h"
#include "base/safe_map.h"
+#include "base/value_object.h"
#include "entrypoints/jni/jni_entrypoints.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "handle_scope.h"
@@ -41,6 +39,7 @@
#include "managed_stack.h"
#include "offsets.h"
#include "read_barrier_config.h"
+#include "runtime_globals.h"
#include "runtime_stats.h"
#include "suspend_reason.h"
#include "thread_state.h"
@@ -471,16 +470,7 @@
Context* GetLongJumpContext();
void ReleaseLongJumpContext(Context* context) {
if (tlsPtr_.long_jump_context != nullptr) {
- // Each QuickExceptionHandler gets a long jump context and uses
- // it for doing the long jump, after finding catch blocks/doing deoptimization.
- // Both finding catch blocks and deoptimization can trigger another
- // exception such as a result of class loading. So there can be nested
- // cases of exception handling and multiple contexts being used.
- // ReleaseLongJumpContext tries to save the context in tlsPtr_.long_jump_context
- // for reuse so there is no need to always allocate a new one each time when
- // getting a context. Since we only keep one context for reuse, delete the
- // existing one since the passed in context is yet to be used for longjump.
- delete tlsPtr_.long_jump_context;
+ ReleaseLongJumpContextInternal();
}
tlsPtr_.long_jump_context = context;
}
@@ -819,19 +809,7 @@
return tlsPtr_.stack_size - (tlsPtr_.stack_end - tlsPtr_.stack_begin);
}
- uint8_t* GetStackEndForInterpreter(bool implicit_overflow_check) const {
- uint8_t* end = tlsPtr_.stack_end + (implicit_overflow_check
- ? GetStackOverflowReservedBytes(kRuntimeISA)
- : 0);
- if (kIsDebugBuild) {
- // In a debuggable build, but especially under ASAN, the access-checks interpreter has a
- // potentially humongous stack size. We don't want to take too much of the stack regularly,
- // so do not increase the regular reserved size (for compiled code etc) and only report the
- // virtually smaller stack to the interpreter here.
- end += GetStackOverflowReservedBytes(kRuntimeISA);
- }
- return end;
- }
+ ALWAYS_INLINE uint8_t* GetStackEndForInterpreter(bool implicit_overflow_check) const;
uint8_t* GetStackEnd() const {
return tlsPtr_.stack_end;
@@ -841,11 +819,7 @@
void SetStackEndForStackOverflow() REQUIRES_SHARED(Locks::mutator_lock_);
// Set the stack end to that to be used during regular execution
- void ResetDefaultStackEnd() {
- // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room
- // to throw a StackOverflowError.
- tlsPtr_.stack_end = tlsPtr_.stack_begin + GetStackOverflowReservedBytes(kRuntimeISA);
- }
+ ALWAYS_INLINE void ResetDefaultStackEnd();
bool IsHandlingStackOverflow() const {
return tlsPtr_.stack_end == tlsPtr_.stack_begin;
@@ -1425,6 +1399,8 @@
static bool IsAotCompiler();
+ void ReleaseLongJumpContextInternal();
+
// 32 bits of atomically changed state and flags. Keeping as 32 bits allows and atomic CAS to
// change from being Suspended to Runnable without a suspend request occurring.
union PACKED(4) StateAndFlags {
diff --git a/runtime/thread_state.h b/runtime/thread_state.h
index 8edfeec..e57a040 100644
--- a/runtime/thread_state.h
+++ b/runtime/thread_state.h
@@ -17,7 +17,7 @@
#ifndef ART_RUNTIME_THREAD_STATE_H_
#define ART_RUNTIME_THREAD_STATE_H_
-#include <ostream>
+#include <iosfwd>
namespace art {
diff --git a/runtime/trace.cc b/runtime/trace.cc
index ce955d8..074e846 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -38,6 +38,8 @@
#include "entrypoints/quick/quick_entrypoints.h"
#include "gc/scoped_gc_critical_section.h"
#include "instrumentation.h"
+#include "jit/jit.h"
+#include "jit/jit_code_cache.h"
#include "mirror/class-inl.h"
#include "mirror/dex_cache-inl.h"
#include "mirror/object-inl.h"
@@ -390,6 +392,15 @@
// Enable count of allocs if specified in the flags.
bool enable_stats = false;
+ if (runtime->GetJit() != nullptr) {
+ // TODO b/110263880 It would be better if we didn't need to do this.
+ // Since we need to hold the method entrypoint across a suspend to ensure instrumentation
+ // hooks are called correctly we have to disable jit-gc to ensure that the entrypoint doesn't
+ // go away. Furthermore we need to leave this off permanently since one could get the same
+ // effect by causing this to be toggled on and off.
+ runtime->GetJit()->GetCodeCache()->SetGarbageCollectCode(false);
+ }
+
// Create Trace object.
{
// Required since EnableMethodTracing calls ConfigureStubs which visits class linker classes.
diff --git a/runtime/trace.h b/runtime/trace.h
index 582f756..567f6ed 100644
--- a/runtime/trace.h
+++ b/runtime/trace.h
@@ -27,12 +27,12 @@
#include <vector>
#include "base/atomic.h"
-#include "base/globals.h"
#include "base/locks.h"
#include "base/macros.h"
#include "base/os.h"
#include "base/safe_map.h"
#include "instrumentation.h"
+#include "runtime_globals.h"
namespace unix_file {
class FdFile;
diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h
index c0ea6be..3512efe 100644
--- a/runtime/utils/dex_cache_arrays_layout-inl.h
+++ b/runtime/utils/dex_cache_arrays_layout-inl.h
@@ -22,10 +22,10 @@
#include <android-base/logging.h>
#include "base/bit_utils.h"
-#include "base/globals.h"
#include "dex/primitive.h"
#include "gc_root.h"
#include "mirror/dex_cache.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 1679821..91eba21 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2654,6 +2654,7 @@
// See if instance-of was preceded by a move-object operation, common due to the small
// register encoding space of instance-of, and propagate type information to the source
// of the move-object.
+ // Note: this is only valid if the move source was not clobbered.
uint32_t move_idx = instance_of_idx - 1;
while (0 != move_idx && !GetInstructionFlags(move_idx).IsOpcode()) {
move_idx--;
@@ -2663,28 +2664,25 @@
work_insn_idx_)) {
break;
}
+ auto maybe_update_fn = [&instance_of_inst, update_line, this, &cast_type](
+ uint16_t move_src,
+ uint16_t move_trg)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (move_trg == instance_of_inst.VRegB_22c() &&
+ move_src != instance_of_inst.VRegA_22c()) {
+ update_line->SetRegisterType<LockOp::kKeep>(this, move_src, cast_type);
+ }
+ };
const Instruction& move_inst = code_item_accessor_.InstructionAt(move_idx);
switch (move_inst.Opcode()) {
case Instruction::MOVE_OBJECT:
- if (move_inst.VRegA_12x() == instance_of_inst.VRegB_22c()) {
- update_line->SetRegisterType<LockOp::kKeep>(this,
- move_inst.VRegB_12x(),
- cast_type);
- }
+ maybe_update_fn(move_inst.VRegB_12x(), move_inst.VRegA_12x());
break;
case Instruction::MOVE_OBJECT_FROM16:
- if (move_inst.VRegA_22x() == instance_of_inst.VRegB_22c()) {
- update_line->SetRegisterType<LockOp::kKeep>(this,
- move_inst.VRegB_22x(),
- cast_type);
- }
+ maybe_update_fn(move_inst.VRegB_22x(), move_inst.VRegA_22x());
break;
case Instruction::MOVE_OBJECT_16:
- if (move_inst.VRegA_32x() == instance_of_inst.VRegB_22c()) {
- update_line->SetRegisterType<LockOp::kKeep>(this,
- move_inst.VRegB_32x(),
- cast_type);
- }
+ maybe_update_fn(move_inst.VRegB_32x(), move_inst.VRegA_32x());
break;
default:
break;
diff --git a/runtime/verify_object.cc b/runtime/verify_object.cc
index 70ca13f..2b8c7da 100644
--- a/runtime/verify_object.cc
+++ b/runtime/verify_object.cc
@@ -17,11 +17,11 @@
#include "verify_object-inl.h"
#include "base/bit_utils.h"
-#include "base/globals.h"
#include "gc/heap.h"
#include "mirror/object-inl.h"
#include "obj_ptr-inl.h"
#include "runtime.h"
+#include "runtime_globals.h"
namespace art {
diff --git a/test/1001-app-image-regions/app_image_regions.cc b/test/1001-app-image-regions/app_image_regions.cc
new file mode 100644
index 0000000..dc16a84
--- /dev/null
+++ b/test/1001-app-image-regions/app_image_regions.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019 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 "jni.h"
+
+#include "gc/heap.h"
+#include "gc/space/image_space.h"
+#include "gc/space/space-inl.h"
+#include "gc/space/region_space.h"
+#include "image.h"
+#include "mirror/class.h"
+#include "runtime.h"
+#include "scoped_thread_state_change-inl.h"
+
+namespace art {
+
+namespace {
+
+extern "C" JNIEXPORT jint JNICALL Java_Main_getRegionSize(JNIEnv*, jclass) {
+ return gc::space::RegionSpace::kRegionSize;
+}
+
+extern "C" JNIEXPORT jint JNICALL Java_Main_checkAppImageSectionSize(JNIEnv*, jclass, jclass c) {
+ ScopedObjectAccess soa(Thread::Current());
+ ObjPtr<mirror::Class> klass_ptr = soa.Decode<mirror::Class>(c);
+ for (auto* space : Runtime::Current()->GetHeap()->GetContinuousSpaces()) {
+ if (space->IsImageSpace()) {
+ auto* image_space = space->AsImageSpace();
+ const auto& image_header = image_space->GetImageHeader();
+ if (image_header.IsAppImage() && image_space->HasAddress(klass_ptr.Ptr())) {
+ return image_header.GetObjectsSection().Size();
+ }
+ }
+ }
+ return 0;
+}
+
+} // namespace
+
+} // namespace art
diff --git a/test/1001-app-image-regions/build b/test/1001-app-image-regions/build
new file mode 100755
index 0000000..16c3a5b
--- /dev/null
+++ b/test/1001-app-image-regions/build
@@ -0,0 +1,34 @@
+#!/bin/bash
+#
+# Copyright 2019 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
+
+count=10000
+echo "LMain;" >> profile
+for i in $(seq 1 "$count"); do
+ echo "LOther\$Inner${i};" >> "profile"
+done
+
+# Generate the other class.
+other_file="src/Other.java"
+echo "class Other {" >> "${other_file}"
+for i in $(seq 1 "$count"); do
+ echo " static class Inner${i} { void test(){} }" >> "${other_file}"
+done
+echo "}" >> "${other_file}"
+
+./default-build "$@"
diff --git a/test/1001-app-image-regions/expected.txt b/test/1001-app-image-regions/expected.txt
new file mode 100644
index 0000000..9fd87ca
--- /dev/null
+++ b/test/1001-app-image-regions/expected.txt
@@ -0,0 +1,4 @@
+JNI_OnLoad called
+App image loaded true
+Region size 262144
+App image section size large enough true
diff --git a/test/1001-app-image-regions/info.txt b/test/1001-app-image-regions/info.txt
new file mode 100644
index 0000000..b13f276
--- /dev/null
+++ b/test/1001-app-image-regions/info.txt
@@ -0,0 +1 @@
+Tests that an app image with many classes is generated and loaded correctly.
diff --git a/test/1001-app-image-regions/run b/test/1001-app-image-regions/run
new file mode 100644
index 0000000..128aa2e
--- /dev/null
+++ b/test/1001-app-image-regions/run
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright (C) 2019 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.
+
+exec ${RUN} $@ --profile -Xcompiler-option --compiler-filter=speed-profile
diff --git a/test/1001-app-image-regions/src/Main.java b/test/1001-app-image-regions/src/Main.java
new file mode 100644
index 0000000..c41a606
--- /dev/null
+++ b/test/1001-app-image-regions/src/Main.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 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.
+ */
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+class Main {
+ public static void main(String[] args) {
+ System.loadLibrary(args[0]);
+ System.out.println("App image loaded " + checkAppImageLoaded());
+ int regionSize = getRegionSize();
+ int objectsSectionSize = checkAppImageSectionSize(Main.class);
+ System.out.println("Region size " + regionSize);
+ System.out.println("App image section size large enough " + (objectsSectionSize > regionSize));
+ if (objectsSectionSize <= regionSize) {
+ System.out.println("Section size " + objectsSectionSize);
+ }
+ }
+
+ public static native boolean checkAppImageLoaded();
+ public static native int getRegionSize();
+ public static native int checkAppImageSectionSize(Class c);
+}
diff --git a/test/689-zygote-jit-deopt/expected.txt b/test/689-zygote-jit-deopt/expected.txt
new file mode 100644
index 0000000..6a5618e
--- /dev/null
+++ b/test/689-zygote-jit-deopt/expected.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/689-zygote-jit-deopt/info.txt b/test/689-zygote-jit-deopt/info.txt
new file mode 100644
index 0000000..100032e
--- /dev/null
+++ b/test/689-zygote-jit-deopt/info.txt
@@ -0,0 +1,2 @@
+Regression test for debuggable apps that need to deoptimize
+methods JIT-compiled by the zygote.
diff --git a/test/689-zygote-jit-deopt/src/Main.java b/test/689-zygote-jit-deopt/src/Main.java
new file mode 100644
index 0000000..330663e
--- /dev/null
+++ b/test/689-zygote-jit-deopt/src/Main.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 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[] args) {
+ System.loadLibrary(args[0]);
+ if (!hasJit()) {
+ return;
+ }
+ ensureJitCompiled(Object.class, "toString");
+ transitionJitFromZygote();
+ deoptimizeBootImage();
+ if (hasJitCompiledEntrypoint(Object.class, "toString")) {
+ throw new Error("Expected Object.toString to be deoptimized");
+ }
+ }
+
+ private static native boolean hasJit();
+ private static native void ensureJitCompiled(Class<?> cls, String name);
+ private static native boolean hasJitCompiledEntrypoint(Class<?> cls, String name);
+ private static native void deoptimizeBootImage();
+ private static native void transitionJitFromZygote();
+}
diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt
index f3c3f03..291de72 100644
--- a/test/800-smali/expected.txt
+++ b/test/800-smali/expected.txt
@@ -73,4 +73,5 @@
b/30458218
b/31313170
ConstClassAliasing
+b/121191566
Done!
diff --git a/test/800-smali/smali/b_121191566.smali b/test/800-smali/smali/b_121191566.smali
new file mode 100644
index 0000000..bcf9ef5
--- /dev/null
+++ b/test/800-smali/smali/b_121191566.smali
@@ -0,0 +1,26 @@
+.class public LB121191566;
+.super Ljava/lang/Object;
+
+
+.method public constructor <init>()V
+.registers 1
+ invoke-direct {p0}, Ljava/lang/Object;-><init>()V
+ return-void
+.end method
+
+.method public static run(Ljava/lang/Object;)Z
+.registers 5
+ move-object v3, v4
+ instance-of v4, v3, Ljava/lang/String;
+ if-eqz v4, :Branch
+ # The peephole must not overwrite v4 (from the move-object). Use an integral move
+ # to check.
+ move v0, v4
+ goto :End
+:Branch
+ # See above.
+ move v0, v4
+:End
+ # Triple-check: the merge should be consistent.
+ return v0
+.end method
diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java
index 9b06e9e..d7979e1 100644
--- a/test/800-smali/src/Main.java
+++ b/test/800-smali/src/Main.java
@@ -193,6 +193,8 @@
testCases.add(new TestCase("b/31313170", "B31313170", "run", null, null, 0));
testCases.add(new TestCase("ConstClassAliasing", "ConstClassAliasing", "run", null, null,
null, true));
+ testCases.add(new TestCase("b/121191566", "B121191566", "run", new Object[] { "a" }, null,
+ true, false));
}
public void runTests() {
diff --git a/test/Android.bp b/test/Android.bp
index 57fcd86..467a717 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -495,6 +495,7 @@
"708-jit-cache-churn/jit.cc",
"800-smali/jni.cc",
"909-attach-agent/disallow_debugging.cc",
+ "1001-app-image-regions/app_image_regions.cc",
"1947-breakpoint-redefine-deopt/check_deopt.cc",
"common/runtime_state.cc",
"common/stack_inspect.cc",
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index 55631a9..bbc3039 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -161,6 +161,19 @@
return !interpreter;
}
+static ArtMethod* GetMethod(ScopedObjectAccess& soa, jclass cls, const ScopedUtfChars& chars)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ CHECK(chars.c_str() != nullptr);
+ ArtMethod* method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
+ chars.c_str(), kRuntimePointerSize);
+ if (method == nullptr) {
+ method = soa.Decode<mirror::Class>(cls)->FindDeclaredVirtualMethodByName(
+ chars.c_str(), kRuntimePointerSize);
+ }
+ DCHECK(method != nullptr) << "Unable to find method called " << chars.c_str();
+ return method;
+}
+
extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJitCompiledEntrypoint(JNIEnv* env,
jclass,
jclass cls,
@@ -172,9 +185,7 @@
Thread* self = Thread::Current();
ScopedObjectAccess soa(self);
ScopedUtfChars chars(env, method_name);
- CHECK(chars.c_str() != nullptr);
- ArtMethod* method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
- chars.c_str(), kRuntimePointerSize);
+ ArtMethod* method = GetMethod(soa, cls, chars);
ScopedAssertNoThreadSuspension sants(__FUNCTION__);
return jit->GetCodeCache()->ContainsPc(
Runtime::Current()->GetInstrumentation()->GetCodeForInvoke(method));
@@ -191,9 +202,7 @@
Thread* self = Thread::Current();
ScopedObjectAccess soa(self);
ScopedUtfChars chars(env, method_name);
- CHECK(chars.c_str() != nullptr);
- ArtMethod* method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
- chars.c_str(), kRuntimePointerSize);
+ ArtMethod* method = GetMethod(soa, cls, chars);
return jit->GetCodeCache()->ContainsMethod(method);
}
@@ -262,14 +271,7 @@
ScopedObjectAccess soa(self);
ScopedUtfChars chars(env, method_name);
- CHECK(chars.c_str() != nullptr);
- method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
- chars.c_str(), kRuntimePointerSize);
- if (method == nullptr) {
- method = soa.Decode<mirror::Class>(cls)->FindDeclaredVirtualMethodByName(
- chars.c_str(), kRuntimePointerSize);
- }
- DCHECK(method != nullptr) << "Unable to find method called " << chars.c_str();
+ method = GetMethod(soa, cls, chars);
}
ForceJitCompiled(self, method);
}
@@ -353,4 +355,20 @@
return (jit != nullptr) ? jit->HotMethodThreshold() : 0;
}
+extern "C" JNIEXPORT void JNICALL Java_Main_transitionJitFromZygote(JNIEnv*, jclass) {
+ jit::Jit* jit = Runtime::Current()->GetJit();
+ if (jit == nullptr) {
+ return;
+ }
+ // Mimic the transition behavior a zygote fork would have.
+ jit->PreZygoteFork();
+ jit->GetCodeCache()->PostForkChildAction(/*is_system_server=*/ false, /*is_zygote=*/ false);
+ jit->PostForkChildAction(/*is_zygote=*/ false);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_Main_deoptimizeBootImage(JNIEnv*, jclass) {
+ ScopedSuspendAll ssa(__FUNCTION__);
+ Runtime::Current()->DeoptimizeBootImage();
+}
+
} // namespace art
diff --git a/test/common/stack_inspect.cc b/test/common/stack_inspect.cc
index 393e773..cb011a8 100644
--- a/test/common/stack_inspect.cc
+++ b/test/common/stack_inspect.cc
@@ -18,6 +18,7 @@
#include <android-base/logging.h>
+#include "arch/context.h"
#include "base/mutex.h"
#include "dex/dex_file-inl.h"
#include "jni/jni_internal.h"
diff --git a/test/knownfailures.json b/test/knownfailures.json
index 983c16a..9c01ba9 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -81,11 +81,13 @@
"variant": "no-prebuild"
},
{
- "tests": ["118-noimage-dex2oat"],
+ "tests": ["118-noimage-dex2oat",
+ "1001-app-image-regions"],
"variant": "no-relocate",
"description": ["118-noimage-dex2oat is not broken per-se it just ",
"doesn't work (and isn't meant to) without --prebuild ",
- "--relocate"]
+ "--relocate. 1001-app-image-regions is disabled since it",
+ "doesn't have the app image loaded for no-relocate"]
},
{
"tests" : "629-vdex-speed",
@@ -1085,6 +1087,7 @@
"688-shared-library",
"999-redefine-hiddenapi",
"1000-non-moving-space-stress",
+ "1001-app-image-regions",
"1951-monitor-enter-no-suspend",
"1957-error-ext"],
"variant": "jvm",
diff --git a/tools/buildbot-build.sh b/tools/buildbot-build.sh
index da463d5..ce1a246 100755
--- a/tools/buildbot-build.sh
+++ b/tools/buildbot-build.sh
@@ -73,7 +73,7 @@
exit 1
fi
make_command="make $j_arg $extra_args $showcommands build-art-target-tests $common_targets"
- make_command+=" libjavacrypto-target libnetd_client-target linker toybox toolbox sh"
+ make_command+=" libjavacrypto-target libnetd_client-target linker toybox toolbox sh unzip"
make_command+=" debuggerd su"
make_command+=" libstdc++ "
make_command+=" ${ANDROID_PRODUCT_OUT#"${ANDROID_BUILD_TOP}/"}/system/etc/public.libraries.txt"
@@ -81,8 +81,8 @@
# These targets are needed for the chroot environment.
make_command+=" crash_dump event-log-tags"
fi
- # Build the Runtime APEX.
- make_command+=" com.android.runtime"
+ # Build the Debug Runtime APEX (which is a superset of the Release Runtime APEX).
+ make_command+=" com.android.runtime.debug"
mode_suffix="-target"
fi
diff --git a/tools/cpp-define-generator/globals.def b/tools/cpp-define-generator/globals.def
index 6443a0c..10542622 100644
--- a/tools/cpp-define-generator/globals.def
+++ b/tools/cpp-define-generator/globals.def
@@ -26,6 +26,7 @@
#include "jit/jit.h"
#include "mirror/object.h"
#include "mirror/object_reference.h"
+#include "runtime_globals.h"
#include "stack.h"
#endif
diff --git a/tools/libcore_failures.txt b/tools/libcore_failures.txt
index 3c65b01..3f9ceea 100644
--- a/tools/libcore_failures.txt
+++ b/tools/libcore_failures.txt
@@ -223,5 +223,17 @@
"libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[8]",
"libcore.libcore.net.InetAddressUtilsTest#test_parseNonNumericAddress[9]"
]
+},
+{
+ description: "Apex related",
+ result: EXEC_FAILED,
+ modes: [device],
+ bug: 122642227,
+ names: [
+ "libcore.java.lang.SystemTest#testSystemProperties_mutable",
+ "libcore.libcore.icu.TimeZoneIntegrationTest#testTimeZoneDataVersion",
+ "libcore.libcore.icu.TimeZoneIntegrationTest#testTimeZoneDebugInfo",
+ "libcore.libcore.icu.TimeZoneIntegrationTest#testTzDataSetVersions"
+ ]
}
]
diff --git a/tools/mount-buildbot-apexes.sh b/tools/mount-buildbot-apexes.sh
new file mode 100755
index 0000000..778d634
--- /dev/null
+++ b/tools/mount-buildbot-apexes.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+#
+# Copyright (C) 2019 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.
+
+# Mount Android Runtime and Core Libraries APEX packages required in the chroot directory.
+# This script emulates some the actions performed by `apexd`.
+
+green='\033[0;32m'
+nc='\033[0m'
+
+# Setup as root, as some actions performed here require it.
+adb root
+adb wait-for-device
+
+# Exit early if there is no chroot.
+[[ -n "$ART_TEST_CHROOT" ]] || exit
+
+# Check that ART_TEST_CHROOT is correctly defined.
+[[ "$ART_TEST_CHROOT" = /* ]] || { echo "$ART_TEST_CHROOT is not an absolute path"; exit 1; }
+
+# Check that the "$ART_TEST_CHROOT/apex" directory exists.
+adb shell test -d "$ART_TEST_CHROOT/apex" \
+ || { echo "$ART_TEST_CHROOT/apex does not exist or is not a directory"; exit 1; }
+
+# Create a directory where we extract APEX packages' payloads (ext4 images)
+# under the chroot directory.
+apex_image_dir="/tmp/apex"
+adb shell mkdir -p "$ART_TEST_CHROOT$apex_image_dir"
+
+# activate_system_package APEX_PACKAGE APEX_NAME
+# ----------------------------------------------
+# Extract payload (ext4 image) from system APEX_PACKAGE and mount it as
+# APEX_NAME in `/apex` under the chroot directory.
+activate_system_package() {
+ local apex_package=$1
+ local apex_name=$2
+ local apex_package_path="/system/apex/$apex_package"
+ local abs_mount_point="$ART_TEST_CHROOT/apex/$apex_name"
+ local abs_image_filename="$ART_TEST_CHROOT$apex_image_dir/$apex_name.img"
+
+ # Make sure that the (absolute) path to the mounted ext4 image is less than
+ # 64 characters, which is a hard limit set in the kernel for loop device
+ # filenames (otherwise, we would get an error message from `losetup`, used
+ # by `mount` to manage the loop device).
+ [[ "${#abs_image_filename}" -ge 64 ]] \
+ && { echo "Filename $abs_image_filename is too long to be used with a loop device"; exit 1; }
+
+ echo -e "${green}Activating package $apex_package as $apex_name${nc}"
+
+ # Extract payload (ext4 image). As standard Android builds do not contain
+ # `unzip`, we use the one we built and sync'd to the chroot directory instead.
+ local payload_filename="apex_payload.img"
+ adb shell chroot "$ART_TEST_CHROOT" \
+ /system/bin/unzip -q "$apex_package_path" "$payload_filename" -d "$apex_image_dir"
+ # Rename the extracted payload to have its name match the APEX's name.
+ adb shell mv "$ART_TEST_CHROOT$apex_image_dir/$payload_filename" "$abs_image_filename"
+ # Check that the mount point is available.
+ adb shell mount | grep -q " on $abs_mount_point" && \
+ { echo "$abs_mount_point is already used as mount point"; exit 1; }
+ # Mount the ext4 image.
+ adb shell mkdir -p "$abs_mount_point"
+ adb shell mount -o loop,ro "$abs_image_filename" "$abs_mount_point"
+}
+
+# Activate the Android Runtime APEX.
+# Note: We use the Debug Runtime APEX (which is a superset of the Release Runtime APEX).
+activate_system_package com.android.runtime.debug.apex com.android.runtime
diff --git a/tools/setup-buildbot-device.sh b/tools/setup-buildbot-device.sh
index ef958d6..92b3672 100755
--- a/tools/setup-buildbot-device.sh
+++ b/tools/setup-buildbot-device.sh
@@ -165,4 +165,9 @@
adb shell mkdir -p "$ART_TEST_CHROOT/dev"
adb shell mount | grep -q "^tmpfs on $ART_TEST_CHROOT/dev type tmpfs " \
|| adb shell mount -o bind /dev "$ART_TEST_CHROOT/dev"
+
+ # Create /apex tmpfs in chroot.
+ adb shell mkdir -p "$ART_TEST_CHROOT/apex"
+ adb shell mount | grep -q "^tmpfs on $ART_TEST_CHROOT/apex type tmpfs " \
+ || adb shell mount -t tmpfs -o nodev,noexec,nosuid tmpfs "$ART_TEST_CHROOT/apex"
fi
diff --git a/tools/teardown-buildbot-device.sh b/tools/teardown-buildbot-device.sh
index 6634fb4..7eb5cc3 100755
--- a/tools/teardown-buildbot-device.sh
+++ b/tools/teardown-buildbot-device.sh
@@ -89,6 +89,9 @@
fi
}
+ # Remove /apex from chroot.
+ remove_filesystem_from_chroot apex tmpfs true
+
# Remove /dev from chroot.
remove_filesystem_from_chroot dev tmpfs true
diff --git a/tools/unmount-buildbot-apexes.sh b/tools/unmount-buildbot-apexes.sh
new file mode 100755
index 0000000..8f0ad5f
--- /dev/null
+++ b/tools/unmount-buildbot-apexes.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# Copyright (C) 2019 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.
+
+# Unmount Android Runtime and Core Libraries APEX packages required in the chroot directory.
+# This script emulates some the actions performed by `apexd`.
+
+# This script undoes the work done by tools/mount-buildbot-apexes.sh.
+# Make sure to keep these files in sync.
+
+green='\033[0;32m'
+nc='\033[0m'
+
+# Setup as root, as some actions performed here require it.
+adb root
+adb wait-for-device
+
+# Exit early if there is no chroot.
+[[ -n "$ART_TEST_CHROOT" ]] || exit
+
+# Check that ART_TEST_CHROOT is correctly defined.
+[[ "$ART_TEST_CHROOT" = /* ]] || { echo "$ART_TEST_CHROOT is not an absolute path"; exit 1; }
+
+# Directory containing extracted APEX packages' payloads (ext4 images) under
+# the chroot directory.
+apex_image_dir="/tmp/apex"
+
+# deactivate_system_package APEX_NAME
+# -----------------------------------
+# Unmount APEX_NAME in `/apex` under the chroot directory and delete the
+# corresponding APEX package payload (ext4 image).
+deactivate_system_package() {
+ local apex_name=$1
+ local abs_image_filename="$ART_TEST_CHROOT$apex_image_dir/$apex_name.img"
+ local abs_mount_point="$ART_TEST_CHROOT/apex/$apex_name"
+
+ echo -e "${green}Deactivating package $apex_name${nc}"
+
+ # Unmount the package's payload (ext4 image).
+ if adb shell mount | grep -q "^/dev/block/loop[0-9]\+ on $abs_mount_point type ext4"; then
+ adb shell umount "$abs_mount_point"
+ adb shell rmdir "$abs_mount_point"
+ # Delete the ext4 image.
+ adb shell rm "$abs_image_filename"
+ fi
+}
+
+# Deactivate the Android Runtime APEX.
+deactivate_system_package com.android.runtime
+
+# Delete the image's directory.
+adb shell rmdir "$ART_TEST_CHROOT$apex_image_dir"