summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/code_generator_arm64.cc5
-rw-r--r--compiler/optimizing/loop_optimization.cc5
-rw-r--r--dexlayout/Android.bp1
-rw-r--r--dexlayout/dex_ir.cc6
-rw-r--r--dexlayout/dexlayout.cc7
-rw-r--r--runtime/parsed_options.cc5
-rw-r--r--test/623-checker-loop-regressions/src/Main.java24
-rw-r--r--test/913-heaps/expected.txt133
-rw-r--r--test/913-heaps/heaps.cc4
-rw-r--r--test/913-heaps/src/art/Test913.java9
10 files changed, 132 insertions, 67 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 8faaec1de7..4955562f82 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -90,8 +90,9 @@ static constexpr uint32_t kPackedSwitchCompareJumpThreshold = 7;
constexpr uint32_t kReferenceLoadMinFarOffset = 16 * KB;
// Flags controlling the use of link-time generated thunks for Baker read barriers.
-constexpr bool kBakerReadBarrierLinkTimeThunksEnableForFields = true;
-constexpr bool kBakerReadBarrierLinkTimeThunksEnableForGcRoots = true;
+// Not yet implemented for heap poisoning.
+constexpr bool kBakerReadBarrierLinkTimeThunksEnableForFields = !kPoisonHeapReferences;
+constexpr bool kBakerReadBarrierLinkTimeThunksEnableForGcRoots = !kPoisonHeapReferences;
// Some instructions have special requirements for a temporary, for example
// LoadClass/kBssEntry and LoadString/kBssEntry for Baker read barrier require
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 4710b32e9c..8e88c1ec7f 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -1082,7 +1082,10 @@ bool HLoopOptimization::TrySetSimpleLoopHeader(HBasicBlock* block) {
HInstruction* s = block->GetFirstInstruction();
if (s != nullptr && s->IsSuspendCheck()) {
HInstruction* c = s->GetNext();
- if (c != nullptr && c->IsCondition() && c->GetUses().HasExactlyOneElement()) {
+ if (c != nullptr &&
+ c->IsCondition() &&
+ c->GetUses().HasExactlyOneElement() && // only used for termination
+ !c->HasEnvironmentUses()) { // unlikely, but not impossible
HInstruction* i = c->GetNext();
if (i != nullptr && i->IsIf() && i->InputAt(0) == c) {
iset_->insert(c);
diff --git a/dexlayout/Android.bp b/dexlayout/Android.bp
index e26d051d9d..4b65c5299a 100644
--- a/dexlayout/Android.bp
+++ b/dexlayout/Android.bp
@@ -14,6 +14,7 @@
art_cc_defaults {
name: "libart-dexlayout-defaults",
+ defaults: ["art_defaults"],
host_supported: true,
srcs: [
"dexlayout.cc",
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
index 4905b5c2f6..6bd9da8194 100644
--- a/dexlayout/dex_ir.cc
+++ b/dexlayout/dex_ir.cc
@@ -496,8 +496,8 @@ AnnotationsDirectoryItem* Collections::CreateAnnotationsDirectoryItem(const DexF
dex_file.GetClassAnnotationSet(disk_annotations_item);
AnnotationSetItem* class_annotation = nullptr;
if (class_set_item != nullptr) {
- uint32_t offset = disk_annotations_item->class_annotations_off_;
- class_annotation = CreateAnnotationSetItem(dex_file, class_set_item, offset);
+ uint32_t item_offset = disk_annotations_item->class_annotations_off_;
+ class_annotation = CreateAnnotationSetItem(dex_file, class_set_item, item_offset);
}
const DexFile::FieldAnnotationsItem* fields =
dex_file.GetFieldAnnotations(disk_annotations_item);
@@ -784,7 +784,7 @@ struct FileSectionDescriptor {
std::function<uint32_t(const dex_ir::Collections&)> offset_fn;
};
-static const std::vector<FileSectionDescriptor> kFileSectionDescriptors = {
+static const FileSectionDescriptor kFileSectionDescriptors[] = {
{
"Header",
DexFile::kDexTypeHeaderItem,
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index 0e0d66bd3d..344d735fa7 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -393,6 +393,7 @@ static std::unique_ptr<char[]> IndexString(dex_ir::Header* header,
index = dec_insn->VRegB();
secondary_index = dec_insn->VRegH();
width = 4;
+ break;
default:
break;
} // switch
@@ -1820,7 +1821,11 @@ void DexLayout::OutputDexFile(const DexFile* dex_file) {
LOG(ERROR) << "Could not create dex writer output file: " << output_location;
return;
}
- ftruncate(new_file->Fd(), header_->FileSize());
+ if (ftruncate(new_file->Fd(), header_->FileSize()) != 0) {
+ LOG(ERROR) << "Could not grow dex writer output file: " << output_location;;
+ new_file->Erase();
+ return;
+ }
mem_map_.reset(MemMap::MapFile(header_->FileSize(), PROT_READ | PROT_WRITE, MAP_SHARED,
new_file->Fd(), 0, /*low_4gb*/ false, output_location.c_str(), &error_msg));
} else {
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 0784e599b5..8ffd8bbc90 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -476,7 +476,10 @@ bool ParsedOptions::DoParse(const RuntimeOptions& options,
Usage(nullptr);
return false;
} else if (args.Exists(M::ShowVersion)) {
- UsageMessage(stdout, "ART version %s\n", Runtime::GetVersion());
+ UsageMessage(stdout,
+ "ART version %s %s\n",
+ Runtime::GetVersion(),
+ GetInstructionSetString(kRuntimeISA));
Exit(0);
} else if (args.Exists(M::BootClassPath)) {
LOG(INFO) << "setting boot class path to " << *args.Get(M::BootClassPath);
diff --git a/test/623-checker-loop-regressions/src/Main.java b/test/623-checker-loop-regressions/src/Main.java
index f0b327840c..2b30986ab3 100644
--- a/test/623-checker-loop-regressions/src/Main.java
+++ b/test/623-checker-loop-regressions/src/Main.java
@@ -288,6 +288,28 @@ public class Main {
}
}
+ // A strange function that does not inline.
+ private static void $noinline$foo(boolean x, int n) {
+ if (n < 0)
+ throw new Error("oh no");
+ if (n > 100) {
+ $noinline$foo(!x, n - 1);
+ $noinline$foo(!x, n - 2);
+ $noinline$foo(!x, n - 3);
+ $noinline$foo(!x, n - 4);
+ }
+ }
+
+ // A loop with environment uses of x (the terminating condition). As exposed by bug
+ // b/37247891, the loop can be unrolled, but should handle the (unlikely, but clearly
+ // not impossible) environment uses of the terminating condition in a correct manner.
+ private static void envUsesInCond() {
+ boolean x = false;
+ for (int i = 0; !(x = i >= 1); i++) {
+ $noinline$foo(true, i);
+ }
+ }
+
public static void main(String[] args) {
expectEquals(10, earlyExitFirst(-1));
for (int i = 0; i <= 10; i++) {
@@ -369,6 +391,8 @@ public class Main {
expectEquals(aa[i], bb.charAt(i));
}
+ envUsesInCond();
+
System.out.println("passed");
}
diff --git a/test/913-heaps/expected.txt b/test/913-heaps/expected.txt
index 46e81715bd..702b247819 100644
--- a/test/913-heaps/expected.txt
+++ b/test/913-heaps/expected.txt
@@ -5,8 +5,6 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonR
root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 3000@0 [size=136, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
-0@0 --(array-element@0)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -17,11 +15,13 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -34,11 +34,13 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
@@ -50,7 +52,6 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot
root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 1@1000 [size=16, length=-1]
root@root --(thread)--> 3000@0 [size=136, length=-1]
-0@0 --(array-element@0)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -61,11 +62,13 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -78,11 +81,13 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
root@root --(thread)--> 3000@0 [size=136, length=-1]
@@ -98,13 +103,11 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonR
root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 3000@0 [size=136, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
-0@0 --(array-element@0)--> 3000@0 [size=136, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 [size=16, length=-1]
@@ -115,12 +118,11 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot
root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 1@1000 [size=16, length=-1]
root@root --(thread)--> 3000@0 [size=136, length=-1]
-0@0 --(array-element@0)--> 3000@0 [size=136, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
---
[1@0 (32, 'HelloWorld'), 2@0 (16, '')]
2
@@ -160,16 +162,17 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
10008
--- klass ---
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 [size=16, length=-1]
@@ -179,13 +182,15 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot
root@root --(thread)--> 1@1000 [size=16, length=-1]
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
--- heap_filter ---
---- tagged objects
@@ -199,8 +204,6 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonR
root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 3000@0 [size=136, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
-0@0 --(array-element@0)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -211,11 +214,13 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -228,11 +233,13 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
@@ -244,7 +251,6 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot
root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 1@1000 [size=16, length=-1]
root@root --(thread)--> 3000@0 [size=136, length=-1]
-0@0 --(array-element@0)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -255,11 +261,13 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -272,11 +280,13 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
---- tagged classes
@@ -284,7 +294,6 @@ root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0
root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 3000@0 [size=136, length=-1]
-0@0 --(array-element@0)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -294,6 +303,7 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -305,12 +315,12 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 3000@0 [size=136, length=-1]
-0@0 --(array-element@0)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -320,6 +330,7 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -331,24 +342,26 @@ root@root --(thread)--> 3000@0 [size=136, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
---- untagged classes
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
1@1000 --(field@3)--> 3@1001 [size=24, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
1@1000 --(field@3)--> 3@1001 [size=24, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 [size=16, length=-1]
@@ -359,14 +372,16 @@ root@root --(thread)--> 1@1000 [size=16, length=-1]
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
1@1000 --(field@3)--> 3@1001 [size=24, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
1@1000 --(field@3)--> 3@1001 [size=24, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
diff --git a/test/913-heaps/heaps.cc b/test/913-heaps/heaps.cc
index 8c06803cc4..19e12ae731 100644
--- a/test/913-heaps/heaps.cc
+++ b/test/913-heaps/heaps.cc
@@ -147,6 +147,10 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
reference_info->stack_local.thread_tag != 3000) {
return 0;
}
+ // Ignore array elements with an untagged source. These are from the environment.
+ if (reference_kind == JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT && *referrer_tag_ptr == 0) {
+ return 0;
+ }
// Only check tagged objects.
if (tag == 0) {
diff --git a/test/913-heaps/src/art/Test913.java b/test/913-heaps/src/art/Test913.java
index 2eb05ef696..d3b29cf2b5 100644
--- a/test/913-heaps/src/art/Test913.java
+++ b/test/913-heaps/src/art/Test913.java
@@ -371,6 +371,14 @@ public class Test913 {
cInst.baz2 = aInst;
v.add(cInstStr, aInstStr); // C -->(field) --> A.
+ A[] aArray = new A[2];
+ setTag(aArray, 500);
+ aArray[1] = a2Inst;
+ cInst.array = aArray;
+ String aArrayStr = "500@0";
+ v.add(cInstStr, aArrayStr);
+ v.add(aArrayStr, a2InstStr);
+
return aInst;
}
}
@@ -408,6 +416,7 @@ public class Test913 {
public static class C extends B implements I2 {
public A baz;
public A baz2;
+ public A[] array;
public C() {}
public C(A a, A b) {