summaryrefslogtreecommitdiff
path: root/compiler/optimizing/intrinsics.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2018-06-05 12:51:04 +0100
committer Vladimir Marko <vmarko@google.com> 2018-06-07 14:24:02 +0100
commitf75613cb7c5cda6a4603ab7041d6f98ec62a80cd (patch)
tree5d253108db708da20e0bbf55a5f3d8e2f8bce4d7 /compiler/optimizing/intrinsics.cc
parent2b40dd35c65ad644d448611750f5b577e97594a1 (diff)
Keep objects for Integer.valueOf() intrinsic alive.
Keep boot image objects referenced by the intrinsic alive through boot image roots, so that they can never be dead as the intrinsic would still be able to resurrect them later. Note that currently the GC considers all boot image objects live forever. That risks leaking memory and should be fixed. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 71526895 Change-Id: Iec25cc27e9c5c4bd3c5711991e3111bfb19ef182
Diffstat (limited to 'compiler/optimizing/intrinsics.cc')
-rw-r--r--compiler/optimizing/intrinsics.cc45
1 files changed, 19 insertions, 26 deletions
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index 056f533398..02f736d775 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -272,34 +272,33 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo
ClassLinker* class_linker = runtime->GetClassLinker();
gc::Heap* heap = runtime->GetHeap();
IntegerValueOfInfo info;
- info.integer_cache =
- class_linker->FindSystemClass(self, "Ljava/lang/Integer$IntegerCache;").Ptr();
- if (info.integer_cache == nullptr) {
- self->ClearException();
+ info.integer_cache = class_linker->LookupClass(self,
+ "Ljava/lang/Integer$IntegerCache;",
+ /* class_loader */ nullptr).Ptr();
+ if (info.integer_cache == nullptr || !info.integer_cache->IsInitialized()) {
+ // Optimization only works if the class is initialized.
return info;
}
- if (!heap->ObjectIsInBootImageSpace(info.integer_cache) || !info.integer_cache->IsInitialized()) {
- // Optimization only works if the class is initialized and in the boot image.
+ if (!heap->ObjectIsInBootImageSpace(info.integer_cache)) {
+ // Optimization only works if the class is in the boot image.
+ // TODO: Implement the intrinsic for boot image compilation.
return info;
}
- info.integer = class_linker->FindSystemClass(self, "Ljava/lang/Integer;").Ptr();
- if (info.integer == nullptr) {
- self->ClearException();
- return info;
- }
- if (!heap->ObjectIsInBootImageSpace(info.integer) || !info.integer->IsInitialized()) {
- // Optimization only works if the class is initialized and in the boot image.
+ info.integer =
+ class_linker->LookupClass(self, "Ljava/lang/Integer;", /* class_loader */ nullptr).Ptr();
+ DCHECK(info.integer != nullptr);
+ DCHECK(info.integer->IsInitialized()); // Must be initialized since IntegerCache is initialized.
+ if (!heap->ObjectIsInBootImageSpace(info.integer)) {
+ // Optimization only works if the class is in the boot image.
return info;
}
ArtField* field = info.integer_cache->FindDeclaredStaticField("cache", "[Ljava/lang/Integer;");
- if (field == nullptr) {
- return info;
- }
+ CHECK(field != nullptr);
info.cache = static_cast<mirror::ObjectArray<mirror::Object>*>(
field->GetObject(info.integer_cache).Ptr());
if (info.cache == nullptr) {
- return info;
+ return info; // Did someone mess up the IntegerCache using reflection?
}
if (!heap->ObjectIsInBootImageSpace(info.cache)) {
@@ -308,21 +307,15 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo
}
field = info.integer->FindDeclaredInstanceField("value", "I");
- if (field == nullptr) {
- return info;
- }
+ CHECK(field != nullptr);
info.value_offset = field->GetOffset().Int32Value();
field = info.integer_cache->FindDeclaredStaticField("low", "I");
- if (field == nullptr) {
- return info;
- }
+ CHECK(field != nullptr);
info.low = field->GetInt(info.integer_cache);
field = info.integer_cache->FindDeclaredStaticField("high", "I");
- if (field == nullptr) {
- return info;
- }
+ CHECK(field != nullptr);
info.high = field->GetInt(info.integer_cache);
DCHECK_EQ(info.cache->GetLength(), info.high - info.low + 1);