8257513: C2: assert((constant_addr - _masm.code()->consts()->start()) == con.offset())

Reviewed-by: kvn, thartmann
This commit is contained in:
Christian Hagedorn 2020-12-21 08:06:48 +00:00
parent fa50877c2e
commit 8e42efaada
4 changed files with 92 additions and 10 deletions
src/hotspot/share/opto
test/hotspot/jtreg/compiler/codecache

@ -114,7 +114,7 @@ void ConstantTable::calculate_offsets_and_size() {
_size = align_up(offset, (int)CodeEntryAlignment);
}
void ConstantTable::emit(CodeBuffer& cb) {
bool ConstantTable::emit(CodeBuffer& cb) const {
MacroAssembler _masm(&cb);
for (int i = 0; i < _constants.length(); i++) {
Constant con = _constants.at(i);
@ -143,12 +143,30 @@ void ConstantTable::emit(CodeBuffer& cb) {
// filled in later in fill_jump_table.
address dummy = (address) n;
constant_addr = _masm.address_constant(dummy);
// Expand jump-table
for (uint i = 1; i < n->outcnt(); i++) {
address temp_addr = _masm.address_constant(dummy + i);
assert(temp_addr, "consts section too small");
if (constant_addr == NULL) {
return false;
}
break;
assert((constant_addr - _masm.code()->consts()->start()) == con.offset(),
"must be: %d == %d", (int)(constant_addr - _masm.code()->consts()->start()), (int)(con.offset()));
// Expand jump-table
address last_addr;
for (uint j = 1; j < n->outcnt(); j++) {
last_addr = _masm.address_constant(dummy + j);
if (last_addr == NULL) {
return false;
}
}
#ifdef ASSERT
address start = _masm.code()->consts()->start();
address new_constant_addr = last_addr - ((n->outcnt() - 1) * sizeof(address));
// Expanding the jump-table could result in an expansion of the const code section.
// In that case, we need to check if the new constant address matches the offset.
assert((constant_addr - start == con.offset()) || (new_constant_addr - start == con.offset()),
"must be: %d == %d or %d == %d (after an expansion)", (int)(constant_addr - start), (int)(con.offset()),
(int)(new_constant_addr - start), (int)(con.offset()));
#endif
continue; // Loop
}
case T_METADATA: {
Metadata* obj = con.get_metadata();
@ -158,10 +176,14 @@ void ConstantTable::emit(CodeBuffer& cb) {
}
default: ShouldNotReachHere();
}
assert(constant_addr, "consts section too small");
if (constant_addr == NULL) {
return false;
}
assert((constant_addr - _masm.code()->consts()->start()) == con.offset(),
"must be: %d == %d", (int) (constant_addr - _masm.code()->consts()->start()), (int)(con.offset()));
"must be: %d == %d", (int)(constant_addr - _masm.code()->consts()->start()), (int)(con.offset()));
}
return true;
}
int ConstantTable::find_offset(Constant& con) const {

@ -113,7 +113,7 @@ public:
void set_table_base_offset(int x) { assert(_table_base_offset == -1 || x == _table_base_offset, "can't change"); _table_base_offset = x; }
int table_base_offset() const { assert(_table_base_offset != -1, "not set yet"); return _table_base_offset; }
void emit(CodeBuffer& cb);
bool emit(CodeBuffer& cb) const;
// Returns the offset of the last entry (the top) of the constant table.
int top_offset() const { assert(_constants.top().offset() != -1, "not bound yet"); return _constants.top().offset(); }

@ -1425,7 +1425,10 @@ void PhaseOutput::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
// Emit the constant table.
if (C->has_mach_constant_base_node()) {
constant_table().emit(*cb);
if (!constant_table().emit(*cb)) {
C->record_failure("consts section overflow");
return;
}
}
// Create an array of labels, one for each basic block

@ -0,0 +1,57 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8257513
* @requires vm.debug == true
* @summary Stress testing code buffers resulted in an assertion failure due to not taking expand calls into account
* which can fail more often with -XX:+StressCodeBuffers. Perform some more sanity flag testing.
* @run main/othervm -Xcomp -XX:-TieredCompilation -XX:+StressCodeBuffers compiler.codecache.TestStressCodeBuffers
* @run main/othervm -Xcomp -XX:+StressCodeBuffers compiler.codecache.TestStressCodeBuffers
*/
package compiler.codecache;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class TestStressCodeBuffers {
static MethodHandle permh;
public static void main(String[] args) throws Exception {
test();
}
public static void test() throws Exception {
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
MethodHandle mh = lookup.findStatic(TestStressCodeBuffers.class, "bar",
MethodType.methodType(void.class, int.class, long.class));
permh = MethodHandles.permuteArguments(mh, mh.type(), 0, 1); // Triggers assertion failure
}
public static void bar(int x, long y) {}
}