Skip to content

Commit 8e42efa

Browse files
committed
8257513: C2: assert((constant_addr - _masm.code()->consts()->start()) == con.offset())
Reviewed-by: kvn, thartmann
1 parent fa50877 commit 8e42efa

4 files changed

Lines changed: 91 additions & 9 deletions

File tree

src/hotspot/share/opto/constantTable.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ void ConstantTable::calculate_offsets_and_size() {
114114
_size = align_up(offset, (int)CodeEntryAlignment);
115115
}
116116

117-
void ConstantTable::emit(CodeBuffer& cb) {
117+
bool ConstantTable::emit(CodeBuffer& cb) const {
118118
MacroAssembler _masm(&cb);
119119
for (int i = 0; i < _constants.length(); i++) {
120120
Constant con = _constants.at(i);
@@ -143,12 +143,30 @@ void ConstantTable::emit(CodeBuffer& cb) {
143143
// filled in later in fill_jump_table.
144144
address dummy = (address) n;
145145
constant_addr = _masm.address_constant(dummy);
146+
if (constant_addr == NULL) {
147+
return false;
148+
}
149+
assert((constant_addr - _masm.code()->consts()->start()) == con.offset(),
150+
"must be: %d == %d", (int)(constant_addr - _masm.code()->consts()->start()), (int)(con.offset()));
151+
146152
// Expand jump-table
147-
for (uint i = 1; i < n->outcnt(); i++) {
148-
address temp_addr = _masm.address_constant(dummy + i);
149-
assert(temp_addr, "consts section too small");
153+
address last_addr;
154+
for (uint j = 1; j < n->outcnt(); j++) {
155+
last_addr = _masm.address_constant(dummy + j);
156+
if (last_addr == NULL) {
157+
return false;
158+
}
150159
}
151-
break;
160+
#ifdef ASSERT
161+
address start = _masm.code()->consts()->start();
162+
address new_constant_addr = last_addr - ((n->outcnt() - 1) * sizeof(address));
163+
// Expanding the jump-table could result in an expansion of the const code section.
164+
// In that case, we need to check if the new constant address matches the offset.
165+
assert((constant_addr - start == con.offset()) || (new_constant_addr - start == con.offset()),
166+
"must be: %d == %d or %d == %d (after an expansion)", (int)(constant_addr - start), (int)(con.offset()),
167+
(int)(new_constant_addr - start), (int)(con.offset()));
168+
#endif
169+
continue; // Loop
152170
}
153171
case T_METADATA: {
154172
Metadata* obj = con.get_metadata();
@@ -158,10 +176,14 @@ void ConstantTable::emit(CodeBuffer& cb) {
158176
}
159177
default: ShouldNotReachHere();
160178
}
161-
assert(constant_addr, "consts section too small");
179+
180+
if (constant_addr == NULL) {
181+
return false;
182+
}
162183
assert((constant_addr - _masm.code()->consts()->start()) == con.offset(),
163-
"must be: %d == %d", (int) (constant_addr - _masm.code()->consts()->start()), (int)(con.offset()));
184+
"must be: %d == %d", (int)(constant_addr - _masm.code()->consts()->start()), (int)(con.offset()));
164185
}
186+
return true;
165187
}
166188

167189
int ConstantTable::find_offset(Constant& con) const {

src/hotspot/share/opto/constantTable.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class ConstantTable {
113113
void set_table_base_offset(int x) { assert(_table_base_offset == -1 || x == _table_base_offset, "can't change"); _table_base_offset = x; }
114114
int table_base_offset() const { assert(_table_base_offset != -1, "not set yet"); return _table_base_offset; }
115115

116-
void emit(CodeBuffer& cb);
116+
bool emit(CodeBuffer& cb) const;
117117

118118
// Returns the offset of the last entry (the top) of the constant table.
119119
int top_offset() const { assert(_constants.top().offset() != -1, "not bound yet"); return _constants.top().offset(); }

src/hotspot/share/opto/output.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,10 @@ void PhaseOutput::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
14251425

14261426
// Emit the constant table.
14271427
if (C->has_mach_constant_base_node()) {
1428-
constant_table().emit(*cb);
1428+
if (!constant_table().emit(*cb)) {
1429+
C->record_failure("consts section overflow");
1430+
return;
1431+
}
14291432
}
14301433

14311434
// Create an array of labels, one for each basic block
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8257513
27+
* @requires vm.debug == true
28+
* @summary Stress testing code buffers resulted in an assertion failure due to not taking expand calls into account
29+
* which can fail more often with -XX:+StressCodeBuffers. Perform some more sanity flag testing.
30+
* @run main/othervm -Xcomp -XX:-TieredCompilation -XX:+StressCodeBuffers compiler.codecache.TestStressCodeBuffers
31+
* @run main/othervm -Xcomp -XX:+StressCodeBuffers compiler.codecache.TestStressCodeBuffers
32+
*/
33+
34+
package compiler.codecache;
35+
36+
import java.lang.invoke.MethodHandle;
37+
import java.lang.invoke.MethodHandles;
38+
import java.lang.invoke.MethodType;
39+
40+
public class TestStressCodeBuffers {
41+
42+
static MethodHandle permh;
43+
44+
public static void main(String[] args) throws Exception {
45+
test();
46+
}
47+
48+
public static void test() throws Exception {
49+
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
50+
MethodHandle mh = lookup.findStatic(TestStressCodeBuffers.class, "bar",
51+
MethodType.methodType(void.class, int.class, long.class));
52+
permh = MethodHandles.permuteArguments(mh, mh.type(), 0, 1); // Triggers assertion failure
53+
}
54+
55+
public static void bar(int x, long y) {}
56+
}
57+

0 commit comments

Comments
 (0)