提交 72b461cb 编写于 作者: K kvn

6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()

Summary: set Z = 0 (not equal) before repne_scan() to indicate that class was not found when RCX == 0.
Reviewed-by: never, phh
上级 fb4e881d
......@@ -7568,21 +7568,27 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
// Scan RCX words at [RDI] for an occurrence of RAX.
// Set NZ/Z based on last compare.
// Z flag value will not be set by 'repne' if RCX == 0 since 'repne' does
// not change flags (only scas instruction which is repeated sets flags).
// Set Z = 0 (not equal) before 'repne' to indicate that class was not found.
#ifdef _LP64
// This part is tricky, as values in supers array could be 32 or 64 bit wide
// and we store values in objArrays always encoded, thus we need to encode
// the value of rax before repne. Note that rax is dead after the repne.
if (UseCompressedOops) {
encode_heap_oop_not_null(rax);
encode_heap_oop_not_null(rax); // Changes flags.
// The superclass is never null; it would be a basic system error if a null
// pointer were to sneak in here. Note that we have already loaded the
// Klass::super_check_offset from the super_klass in the fast path,
// so if there is a null in that register, we are already in the afterlife.
testl(rax,rax); // Set Z = 0
repne_scanl();
} else
#endif // _LP64
{
testptr(rax,rax); // Set Z = 0
repne_scan();
}
// Unspill the temp. registers:
if (pushed_rdi) pop(rdi);
if (pushed_rcx) pop(rcx);
......@@ -8257,30 +8263,35 @@ void MacroAssembler::store_heap_oop_null(Address dst) {
}
}
// Algorithm must match oop.inline.hpp encode_heap_oop.
void MacroAssembler::encode_heap_oop(Register r) {
#ifdef ASSERT
void MacroAssembler::verify_heapbase(const char* msg) {
assert (UseCompressedOops, "should be compressed");
assert (Universe::heap() != NULL, "java heap should be initialized");
if (Universe::narrow_oop_base() == NULL) {
verify_oop(r, "broken oop in encode_heap_oop");
if (Universe::narrow_oop_shift() != 0) {
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
shrq(r, LogMinObjAlignmentInBytes);
}
return;
}
#ifdef ASSERT
if (CheckCompressedOops) {
Label ok;
push(rscratch1); // cmpptr trashes rscratch1
cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
jcc(Assembler::equal, ok);
stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
stop(msg);
bind(ok);
pop(rscratch1);
}
}
#endif
// Algorithm must match oop.inline.hpp encode_heap_oop.
void MacroAssembler::encode_heap_oop(Register r) {
#ifdef ASSERT
verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
#endif
verify_oop(r, "broken oop in encode_heap_oop");
if (Universe::narrow_oop_base() == NULL) {
if (Universe::narrow_oop_shift() != 0) {
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
shrq(r, LogMinObjAlignmentInBytes);
}
return;
}
testq(r, r);
cmovq(Assembler::equal, r, r12_heapbase);
subq(r, r12_heapbase);
......@@ -8288,9 +8299,8 @@ void MacroAssembler::encode_heap_oop(Register r) {
}
void MacroAssembler::encode_heap_oop_not_null(Register r) {
assert (UseCompressedOops, "should be compressed");
assert (Universe::heap() != NULL, "java heap should be initialized");
#ifdef ASSERT
verify_heapbase("MacroAssembler::encode_heap_oop_not_null: heap base corrupted?");
if (CheckCompressedOops) {
Label ok;
testq(r, r);
......@@ -8310,9 +8320,8 @@ void MacroAssembler::encode_heap_oop_not_null(Register r) {
}
void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
assert (UseCompressedOops, "should be compressed");
assert (Universe::heap() != NULL, "java heap should be initialized");
#ifdef ASSERT
verify_heapbase("MacroAssembler::encode_heap_oop_not_null2: heap base corrupted?");
if (CheckCompressedOops) {
Label ok;
testq(src, src);
......@@ -8335,40 +8344,21 @@ void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
}
void MacroAssembler::decode_heap_oop(Register r) {
assert (UseCompressedOops, "should be compressed");
assert (Universe::heap() != NULL, "java heap should be initialized");
#ifdef ASSERT
verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?");
#endif
if (Universe::narrow_oop_base() == NULL) {
if (Universe::narrow_oop_shift() != 0) {
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
shlq(r, LogMinObjAlignmentInBytes);
}
verify_oop(r, "broken oop in decode_heap_oop");
return;
}
#ifdef ASSERT
if (CheckCompressedOops) {
Label ok;
push(rscratch1);
cmpptr(r12_heapbase,
ExternalAddress((address)Universe::narrow_oop_base_addr()));
jcc(Assembler::equal, ok);
stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
bind(ok);
pop(rscratch1);
} else {
Label done;
shlq(r, LogMinObjAlignmentInBytes);
jccb(Assembler::equal, done);
addq(r, r12_heapbase);
bind(done);
}
#endif
Label done;
shlq(r, LogMinObjAlignmentInBytes);
jccb(Assembler::equal, done);
addq(r, r12_heapbase);
#if 0
// alternate decoding probably a wash.
testq(r, r);
jccb(Assembler::equal, done);
leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
#endif
bind(done);
verify_oop(r, "broken oop in decode_heap_oop");
}
......@@ -8410,9 +8400,11 @@ void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
addq(dst, r12_heapbase);
}
}
} else if (dst != src) {
} else {
assert (Universe::narrow_oop_base() == NULL, "sanity");
movq(dst, src);
if (dst != src) {
movq(dst, src);
}
}
}
......
......@@ -1714,6 +1714,9 @@ class MacroAssembler: public Assembler {
// if heap base register is used - reinit it with the correct value
void reinit_heapbase();
DEBUG_ONLY(void verify_heapbase(const char* msg);)
#endif // _LP64
// Int division/remainder for Java
......
......@@ -2442,6 +2442,10 @@ class CommandLineFlags {
"Call fatal if this exception is thrown. Example: " \
"java -XX:AbortVMOnException=java.lang.NullPointerException Foo") \
\
notproduct(ccstr, AbortVMOnExceptionMessage, NULL, \
"Call fatal if the exception pointed by AbortVMOnException " \
"has this message.") \
\
develop(bool, DebugVtables, false, \
"add debugging code to vtable dispatch") \
\
......
......@@ -117,7 +117,7 @@ void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exc
(address)h_exception(), file, line, thread);
}
// for AbortVMOnException flag
NOT_PRODUCT(Exceptions::debug_check_abort(h_exception));
NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message));
// Check for special boot-strapping/vm-thread handling
if (special_exception(thread, file, line, h_exception)) return;
......@@ -375,17 +375,26 @@ ExceptionMark::~ExceptionMark() {
#ifndef PRODUCT
// caller frees value_string if necessary
void Exceptions::debug_check_abort(const char *value_string) {
void Exceptions::debug_check_abort(const char *value_string, const char* message) {
if (AbortVMOnException != NULL && value_string != NULL &&
strstr(value_string, AbortVMOnException)) {
fatal(err_msg("Saw %s, aborting", value_string));
if (AbortVMOnExceptionMessage == NULL || message == NULL ||
strcmp(message, AbortVMOnExceptionMessage) == 0) {
fatal(err_msg("Saw %s, aborting", value_string));
}
}
}
void Exceptions::debug_check_abort(Handle exception) {
void Exceptions::debug_check_abort(Handle exception, const char* message) {
if (AbortVMOnException != NULL) {
ResourceMark rm;
debug_check_abort(instanceKlass::cast(exception()->klass())->external_name());
if (message == NULL && exception->is_a(SystemDictionary::Throwable_klass())) {
oop msg = java_lang_Throwable::message(exception);
if (msg != NULL) {
message = java_lang_String::as_utf8_string(msg);
}
}
debug_check_abort(instanceKlass::cast(exception()->klass())->external_name(), message);
}
}
#endif
......@@ -143,8 +143,8 @@ class Exceptions {
static void throw_stack_overflow_exception(Thread* thread, const char* file, int line);
// for AbortVMOnException flag
NOT_PRODUCT(static void debug_check_abort(Handle exception);)
NOT_PRODUCT(static void debug_check_abort(const char *value_string);)
NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);)
NOT_PRODUCT(static void debug_check_abort(const char *value_string, const char* message = NULL);)
};
......
......@@ -479,8 +479,8 @@ void VMError::report(outputStream* st) {
if (fr.sp()) {
st->print(", sp=" PTR_FORMAT, fr.sp());
st->print(", free space=%" INTPTR_FORMAT "k",
((intptr_t)fr.sp() - (intptr_t)stack_bottom) >> 10);
size_t free_stack_size = pointer_delta(fr.sp(), stack_bottom, 1024);
st->print(", free space=" SIZE_FORMAT "k", free_stack_size);
}
st->cr();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册