mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
6826736: CMS: core dump with -XX:+UseCompressedOops
Fix deoptimization code and OopMapSet::all_do() to check for oop = narrow_oop_base. Reviewed-by: jcoomes, phh, ysr, never
This commit is contained in:
parent
db41917a7e
commit
b0f75657c5
5 changed files with 111 additions and 2 deletions
|
@ -379,6 +379,14 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
|
|||
if ( loc != NULL ) {
|
||||
oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
|
||||
oop *derived_loc = loc;
|
||||
oop val = *base_loc;
|
||||
if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
|
||||
// Ignore NULL oops and decoded NULL narrow oops which
|
||||
// equal to Universe::narrow_oop_base when a narrow oop
|
||||
// implicit null check is used in compiled code.
|
||||
// The narrow_oop_base could be NULL or be the address
|
||||
// of the page below heap depending on compressed oops mode.
|
||||
} else
|
||||
derived_oop_fn(base_loc, derived_loc);
|
||||
}
|
||||
oms.next();
|
||||
|
@ -394,6 +402,15 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
|
|||
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
|
||||
if ( loc != NULL ) {
|
||||
if ( omv.type() == OopMapValue::oop_value ) {
|
||||
oop val = *loc;
|
||||
if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
|
||||
// Ignore NULL oops and decoded NULL narrow oops which
|
||||
// equal to Universe::narrow_oop_base when a narrow oop
|
||||
// implicit null check is used in compiled code.
|
||||
// The narrow_oop_base could be NULL or be the address
|
||||
// of the page below heap depending on compressed oops mode.
|
||||
continue;
|
||||
}
|
||||
#ifdef ASSERT
|
||||
if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
|
||||
!Universe::heap()->is_in_or_null(*loc)) {
|
||||
|
@ -410,6 +427,8 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
|
|||
#endif // ASSERT
|
||||
oop_fn->do_oop(loc);
|
||||
} else if ( omv.type() == OopMapValue::value_value ) {
|
||||
assert((*loc) == (oop)NULL || !Universe::is_narrow_oop_base(*loc),
|
||||
"found invalid value pointer");
|
||||
value_fn->do_oop(loc);
|
||||
} else if ( omv.type() == OopMapValue::narrowoop_value ) {
|
||||
narrowOop *nl = (narrowOop*)loc;
|
||||
|
|
|
@ -233,6 +233,10 @@ class OopMapSet : public ResourceObj {
|
|||
int heap_size() const;
|
||||
void copy_to(address addr);
|
||||
|
||||
// Methods oops_do() and all_do() filter out NULL oops and
|
||||
// oop == Universe::narrow_oop_base() before passing oops
|
||||
// to closures.
|
||||
|
||||
// Iterates through frame for a compiled method
|
||||
static void oops_do (const frame* fr,
|
||||
const RegisterMap* reg_map, OopClosure* f);
|
||||
|
|
|
@ -343,6 +343,7 @@ class Universe: AllStatic {
|
|||
// For UseCompressedOops
|
||||
static address* narrow_oop_base_addr() { return &_narrow_oop._base; }
|
||||
static address narrow_oop_base() { return _narrow_oop._base; }
|
||||
static bool is_narrow_oop_base(void* addr) { return (narrow_oop_base() == (address)addr); }
|
||||
static int narrow_oop_shift() { return _narrow_oop._shift; }
|
||||
static void set_narrow_oop_base(address base) { _narrow_oop._base = base; }
|
||||
static void set_narrow_oop_shift(int shift) { _narrow_oop._shift = shift; }
|
||||
|
|
|
@ -104,7 +104,17 @@ StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* r
|
|||
}
|
||||
#endif
|
||||
case Location::oop: {
|
||||
Handle h(*(oop *)value_addr); // Wrap a handle around the oop
|
||||
oop val = *(oop *)value_addr;
|
||||
#ifdef _LP64
|
||||
if (Universe::is_narrow_oop_base(val)) {
|
||||
// Compiled code may produce decoded oop = narrow_oop_base
|
||||
// when a narrow oop implicit null check is used.
|
||||
// The narrow_oop_base could be NULL or be the address
|
||||
// of the page below heap. Use NULL value for both cases.
|
||||
val = (oop)NULL;
|
||||
}
|
||||
#endif
|
||||
Handle h(val); // Wrap a handle around the oop
|
||||
return new StackValue(h);
|
||||
}
|
||||
case Location::addr: {
|
||||
|
|
75
hotspot/test/compiler/6826736/Test.java
Normal file
75
hotspot/test/compiler/6826736/Test.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6826736
|
||||
* @summary CMS: core dump with -XX:+UseCompressedOops
|
||||
*
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:+ScavengeALot -XX:+UseCompressedOops -XX:HeapBaseMinAddress=32g -XX:CompileThreshold=100 -XX:CompileOnly=Test.test -XX:-BlockLayoutRotateLoops -XX:LoopUnrollLimit=0 Test
|
||||
*/
|
||||
|
||||
public class Test {
|
||||
int[] arr;
|
||||
int[] arr2;
|
||||
int test(int r) {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
for (int j = i; j < 100; j++) {
|
||||
int a = 0;
|
||||
for (long k = 0; k < 100; k++) {
|
||||
a += k;
|
||||
}
|
||||
if (arr != null)
|
||||
a = arr[j];
|
||||
r += a;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int r = 0;
|
||||
Test t = new Test();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
t.arr = new int[100];
|
||||
r = t.test(r);
|
||||
}
|
||||
System.out.println("Warmup 1 is done.");
|
||||
for (int i = 0; i < 100; i++) {
|
||||
t.arr = null;
|
||||
r = t.test(r);
|
||||
}
|
||||
System.out.println("Warmup 2 is done.");
|
||||
for (int i = 0; i < 100; i++) {
|
||||
t.arr = new int[100];
|
||||
r = t.test(r);
|
||||
}
|
||||
System.out.println("Warmup is done.");
|
||||
for (int i = 0; i < 100; i++) {
|
||||
t.arr = new int[1000000];
|
||||
t.arr = null;
|
||||
r = t.test(r);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue