提交 eccfd348 编写于 作者: K kvn

6826736: CMS: core dump with -XX:+UseCompressedOops

Summary: Fix deoptimization code and OopMapSet::all_do() to check for oop = narrow_oop_base.
Reviewed-by: jcoomes, phh, ysr, never
上级 c6f9c8b0
...@@ -379,7 +379,15 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map, ...@@ -379,7 +379,15 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
if ( loc != NULL ) { if ( loc != NULL ) {
oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map); oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
oop *derived_loc = loc; oop *derived_loc = loc;
derived_oop_fn(base_loc, derived_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(); oms.next();
} while (!oms.is_done()); } while (!oms.is_done());
...@@ -394,6 +402,15 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map, ...@@ -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); oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
if ( loc != NULL ) { if ( loc != NULL ) {
if ( omv.type() == OopMapValue::oop_value ) { 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 #ifdef ASSERT
if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) || if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
!Universe::heap()->is_in_or_null(*loc)) { !Universe::heap()->is_in_or_null(*loc)) {
...@@ -410,6 +427,8 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map, ...@@ -410,6 +427,8 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
#endif // ASSERT #endif // ASSERT
oop_fn->do_oop(loc); oop_fn->do_oop(loc);
} else if ( omv.type() == OopMapValue::value_value ) { } 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); value_fn->do_oop(loc);
} else if ( omv.type() == OopMapValue::narrowoop_value ) { } else if ( omv.type() == OopMapValue::narrowoop_value ) {
narrowOop *nl = (narrowOop*)loc; narrowOop *nl = (narrowOop*)loc;
......
...@@ -233,6 +233,10 @@ class OopMapSet : public ResourceObj { ...@@ -233,6 +233,10 @@ class OopMapSet : public ResourceObj {
int heap_size() const; int heap_size() const;
void copy_to(address addr); 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 // Iterates through frame for a compiled method
static void oops_do (const frame* fr, static void oops_do (const frame* fr,
const RegisterMap* reg_map, OopClosure* f); const RegisterMap* reg_map, OopClosure* f);
......
...@@ -343,6 +343,7 @@ class Universe: AllStatic { ...@@ -343,6 +343,7 @@ class Universe: AllStatic {
// For UseCompressedOops // For UseCompressedOops
static address* narrow_oop_base_addr() { return &_narrow_oop._base; } static address* narrow_oop_base_addr() { return &_narrow_oop._base; }
static address narrow_oop_base() { 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 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_base(address base) { _narrow_oop._base = base; }
static void set_narrow_oop_shift(int shift) { _narrow_oop._shift = shift; } 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 ...@@ -104,7 +104,17 @@ StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* r
} }
#endif #endif
case Location::oop: { 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); return new StackValue(h);
} }
case Location::addr: { case Location::addr: {
......
/*
* 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);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册