Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 43ed001

Browse files
Ekaterina VergizovaYuri Nesterenko
authored andcommitted
8239497: SEGV in EdgeUtils::field_name_symbol(Edge const&)
Reviewed-by: yan Backport-of: f2fb5c5
1 parent 72e40e9 commit 43ed001

File tree

6 files changed

+61
-85
lines changed

6 files changed

+61
-85
lines changed

src/hotspot/share/jfr/leakprofiler/chains/edge.cpp

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -36,22 +36,7 @@ const oop Edge::pointee() const {
3636
}
3737

3838
const oop Edge::reference_owner() const {
39-
return is_root() ? (oop)NULL : UnifiedOop::dereference(_parent->reference());
40-
}
41-
42-
static const Klass* resolve_klass(const oop obj) {
43-
assert(obj != NULL, "invariant");
44-
return java_lang_Class::is_instance(obj) ?
45-
java_lang_Class::as_Klass(obj) : obj->klass();
46-
}
47-
48-
const Klass* Edge::pointee_klass() const {
49-
return resolve_klass(pointee());
50-
}
51-
52-
const Klass* Edge::reference_owner_klass() const {
53-
const oop ref_owner = reference_owner();
54-
return ref_owner != NULL ? resolve_klass(ref_owner) : NULL;
39+
return is_root() ? (oop)NULL : _parent->pointee();
5540
}
5641

5742
size_t Edge::distance_to_root() const {

src/hotspot/share/jfr/leakprofiler/chains/edge.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -46,9 +46,7 @@ class Edge {
4646
return _parent == NULL;
4747
}
4848
const oop pointee() const;
49-
const Klass* pointee_klass() const;
5049
const oop reference_owner() const;
51-
const Klass* reference_owner_klass() const;
5250
size_t distance_to_root() const;
5351

5452
void* operator new (size_t sz, void* here) {

src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp

Lines changed: 36 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
3030
#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
3131
#include "oops/fieldStreams.hpp"
3232
#include "oops/instanceKlass.hpp"
33+
#include "oops/instanceMirrorKlass.hpp"
3334
#include "oops/objArrayOop.inline.hpp"
3435
#include "oops/oopsHierarchy.hpp"
3536
#include "runtime/handles.inline.hpp"
@@ -38,60 +39,54 @@ bool EdgeUtils::is_leak_edge(const Edge& edge) {
3839
return (const Edge*)edge.pointee()->mark() == &edge;
3940
}
4041

41-
static int field_offset(const StoredEdge& edge) {
42-
assert(!edge.is_root(), "invariant");
43-
const oop ref_owner = edge.reference_owner();
42+
static bool is_static_field(const oop ref_owner, const InstanceKlass* ik, int offset) {
43+
assert(ref_owner != NULL, "invariant");
44+
assert(ik != NULL, "invariant");
45+
assert(ref_owner->klass() == ik, "invariant");
46+
return ik->is_mirror_instance_klass() && offset >= InstanceMirrorKlass::cast(ik)->offset_of_static_fields();
47+
}
48+
49+
static int field_offset(const Edge& edge, const oop ref_owner) {
4450
assert(ref_owner != NULL, "invariant");
51+
assert(!ref_owner->is_array(), "invariant");
52+
assert(ref_owner->is_instance(), "invariant");
4553
const oop* reference = UnifiedOop::decode(edge.reference());
4654
assert(reference != NULL, "invariant");
4755
assert(!UnifiedOop::is_narrow(reference), "invariant");
48-
assert(!ref_owner->is_array(), "invariant");
49-
assert(ref_owner->is_instance(), "invariant");
5056
const int offset = (int)pointer_delta(reference, ref_owner, sizeof(char));
51-
assert(offset < (ref_owner->size() * HeapWordSize), "invariant");
57+
assert(offset < ref_owner->size() * HeapWordSize, "invariant");
5258
return offset;
5359
}
5460

55-
static const InstanceKlass* field_type(const StoredEdge& edge) {
56-
assert(!edge.is_root() || !EdgeUtils::is_array_element(edge), "invariant");
57-
return (const InstanceKlass*)edge.reference_owner_klass();
58-
}
59-
60-
const Symbol* EdgeUtils::field_name_symbol(const Edge& edge) {
61+
const Symbol* EdgeUtils::field_name(const Edge& edge, jshort* modifiers) {
6162
assert(!edge.is_root(), "invariant");
62-
assert(!is_array_element(edge), "invariant");
63-
const int offset = field_offset(edge);
64-
const InstanceKlass* ik = field_type(edge);
63+
assert(!EdgeUtils::is_array_element(edge), "invariant");
64+
assert(modifiers != NULL, "invariant");
65+
const oop ref_owner = edge.reference_owner();
66+
assert(ref_owner != NULL, "invariant");
67+
assert(ref_owner->klass()->is_instance_klass(), "invariant");
68+
const InstanceKlass* ik = InstanceKlass::cast(ref_owner->klass());
69+
const int offset = field_offset(edge, ref_owner);
70+
if (is_static_field(ref_owner, ik, offset)) {
71+
assert(ik->is_mirror_instance_klass(), "invariant");
72+
assert(java_lang_Class::as_Klass(ref_owner)->is_instance_klass(), "invariant");
73+
ik = InstanceKlass::cast(java_lang_Class::as_Klass(ref_owner));
74+
}
6575
while (ik != NULL) {
6676
JavaFieldStream jfs(ik);
6777
while (!jfs.done()) {
6878
if (offset == jfs.offset()) {
79+
*modifiers = jfs.access_flags().as_short();
6980
return jfs.name();
7081
}
7182
jfs.next();
7283
}
73-
ik = (InstanceKlass*)ik->super();
84+
ik = (const InstanceKlass*)ik->super();
7485
}
86+
*modifiers = 0;
7587
return NULL;
7688
}
7789

78-
jshort EdgeUtils::field_modifiers(const Edge& edge) {
79-
const int offset = field_offset(edge);
80-
const InstanceKlass* ik = field_type(edge);
81-
82-
while (ik != NULL) {
83-
JavaFieldStream jfs(ik);
84-
while (!jfs.done()) {
85-
if (offset == jfs.offset()) {
86-
return jfs.access_flags().as_short();
87-
}
88-
jfs.next();
89-
}
90-
ik = (InstanceKlass*)ik->super();
91-
}
92-
return 0;
93-
}
94-
9590
bool EdgeUtils::is_array_element(const Edge& edge) {
9691
assert(!edge.is_root(), "invariant");
9792
const oop ref_owner = edge.reference_owner();
@@ -100,7 +95,7 @@ bool EdgeUtils::is_array_element(const Edge& edge) {
10095
}
10196

10297
static int array_offset(const Edge& edge) {
103-
assert(!edge.is_root(), "invariant");
98+
assert(EdgeUtils::is_array_element(edge), "invariant");
10499
const oop ref_owner = edge.reference_owner();
105100
assert(ref_owner != NULL, "invariant");
106101
const oop* reference = UnifiedOop::decode(edge.reference());
@@ -114,17 +109,15 @@ static int array_offset(const Edge& edge) {
114109
}
115110

116111
int EdgeUtils::array_index(const Edge& edge) {
117-
return is_array_element(edge) ? array_offset(edge) : 0;
112+
return array_offset(edge);
118113
}
119114

120115
int EdgeUtils::array_size(const Edge& edge) {
121-
if (is_array_element(edge)) {
122-
const oop ref_owner = edge.reference_owner();
123-
assert(ref_owner != NULL, "invariant");
124-
assert(ref_owner->is_objArray(), "invariant");
125-
return ((objArrayOop)(ref_owner))->length();
126-
}
127-
return 0;
116+
assert(is_array_element(edge), "invariant");
117+
const oop ref_owner = edge.reference_owner();
118+
assert(ref_owner != NULL, "invariant");
119+
assert(ref_owner->is_objArray(), "invariant");
120+
return ((objArrayOop)ref_owner)->length();
128121
}
129122

130123
const Edge* EdgeUtils::root(const Edge& edge) {

src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -44,8 +44,8 @@ class EdgeUtils : public AllStatic {
4444
static int array_index(const Edge& edge);
4545
static int array_size(const Edge& edge);
4646

47-
static const Symbol* field_name_symbol(const Edge& edge);
48-
static jshort field_modifiers(const Edge& edge);
47+
static const Symbol* field_name(const Edge& edge, jshort* modifiers);
48+
4949
};
5050

5151
#endif // SHARE_JFR_LEAKPROFILER_CHAINS_EDGEUTILS_HPP

src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -298,22 +298,20 @@ static traceid get_field_info_id(const Edge& edge) {
298298
if (edge.is_root()) {
299299
return 0;
300300
}
301-
302301
assert(!EdgeUtils::is_array_element(edge), "invariant");
303-
const Symbol* const field_name_symbol = EdgeUtils::field_name_symbol(edge);
302+
jshort field_modifiers;
303+
const Symbol* const field_name_symbol = EdgeUtils::field_name(edge, &field_modifiers);
304304
if (field_name_symbol == NULL) {
305305
return 0;
306306
}
307-
308307
if (field_infos == NULL) {
309308
field_infos = new FieldTable();
310309
}
311310
assert(field_infos != NULL, "invariant");
312-
313311
ObjectSampleFieldInfo* const osfi = new ObjectSampleFieldInfo();
314312
assert(osfi != NULL, "invariant");
315313
osfi->_field_name_symbol = field_name_symbol;
316-
osfi->_field_modifiers = EdgeUtils::field_modifiers(edge);
314+
osfi->_field_modifiers = field_modifiers;
317315
return field_infos->store(osfi);
318316
}
319317

@@ -531,7 +529,7 @@ static void add_old_object_sample_info(const StoredEdge* current, traceid id) {
531529
assert(oosi != NULL, "invariant");
532530
oosi->_id = id;
533531
oosi->_data._object = current->pointee();
534-
oosi->_data._reference_id = current->parent() == NULL ? (traceid)0 : id;
532+
oosi->_data._reference_id = current->parent() == NULL ? 0 : id;
535533
sample_infos->store(oosi);
536534
}
537535

@@ -546,8 +544,8 @@ static void add_reference_info(const StoredEdge* current, traceid id, traceid pa
546544
assert(ri != NULL, "invariant");
547545

548546
ri->_id = id;
549-
ri->_data._array_info_id = !current->is_skip_edge() ? get_array_info_id(*current, id) : 0;
550-
ri->_data._field_info_id = ri->_data._array_info_id == 0 && !current->is_skip_edge() ? get_field_info_id(*current) : (traceid)0;
547+
ri->_data._array_info_id = current->is_skip_edge() ? 0 : get_array_info_id(*current, id);
548+
ri->_data._field_info_id = ri->_data._array_info_id != 0 || current->is_skip_edge() ? 0 : get_field_info_id(*current);
551549
ri->_data._old_object_sample_id = parent_id;
552550
ri->_data._skip = current->skip_length();
553551
ref_infos->store(ri);
@@ -571,11 +569,11 @@ void ObjectSampleWriter::write(const StoredEdge* edge) {
571569
const StoredEdge* const parent = edge->parent();
572570
if (parent != NULL) {
573571
add_reference_info(edge, id, _store->get_id(parent));
574-
} else {
575-
if (is_gc_root(edge)) {
576-
assert(edge->gc_root_id() == id, "invariant");
577-
add_gc_root_info(edge, id);
578-
}
572+
return;
573+
}
574+
if (is_gc_root(edge)) {
575+
assert(edge->gc_root_id() == id, "invariant");
576+
add_gc_root_info(edge, id);
579577
}
580578
}
581579

src/hotspot/share/oops/instanceMirrorKlass.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -55,11 +55,13 @@ class InstanceMirrorKlass: public InstanceKlass {
5555
public:
5656
InstanceMirrorKlass() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
5757

58-
// Casting from Klass*
5958
static InstanceMirrorKlass* cast(Klass* k) {
60-
assert(InstanceKlass::cast(k)->is_mirror_instance_klass(),
61-
"cast to InstanceMirrorKlass");
62-
return static_cast<InstanceMirrorKlass*>(k);
59+
return const_cast<InstanceMirrorKlass*>(cast(const_cast<const Klass*>(k)));
60+
}
61+
62+
static const InstanceMirrorKlass* cast(const Klass* k) {
63+
assert(InstanceKlass::cast(k)->is_mirror_instance_klass(), "cast to InstanceMirrorKlass");
64+
return static_cast<const InstanceMirrorKlass*>(k);
6365
}
6466

6567
// Returns the size of the instance including the extra static fields.

0 commit comments

Comments
 (0)