提交 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, ...@@ -7568,21 +7568,27 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
// Scan RCX words at [RDI] for an occurrence of RAX. // Scan RCX words at [RDI] for an occurrence of RAX.
// Set NZ/Z based on last compare. // 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 #ifdef _LP64
// This part is tricky, as values in supers array could be 32 or 64 bit wide // 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 // 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. // the value of rax before repne. Note that rax is dead after the repne.
if (UseCompressedOops) { 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 // 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 // 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, // 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. // so if there is a null in that register, we are already in the afterlife.
testl(rax,rax); // Set Z = 0
repne_scanl(); repne_scanl();
} else } else
#endif // _LP64 #endif // _LP64
{
testptr(rax,rax); // Set Z = 0
repne_scan(); repne_scan();
}
// Unspill the temp. registers: // Unspill the temp. registers:
if (pushed_rdi) pop(rdi); if (pushed_rdi) pop(rdi);
if (pushed_rcx) pop(rcx); if (pushed_rcx) pop(rcx);
...@@ -8257,30 +8263,35 @@ void MacroAssembler::store_heap_oop_null(Address dst) { ...@@ -8257,30 +8263,35 @@ void MacroAssembler::store_heap_oop_null(Address dst) {
} }
} }
// Algorithm must match oop.inline.hpp encode_heap_oop. #ifdef ASSERT
void MacroAssembler::encode_heap_oop(Register r) { void MacroAssembler::verify_heapbase(const char* msg) {
assert (UseCompressedOops, "should be compressed"); assert (UseCompressedOops, "should be compressed");
assert (Universe::heap() != NULL, "java heap should be initialized"); 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) { if (CheckCompressedOops) {
Label ok; Label ok;
push(rscratch1); // cmpptr trashes rscratch1 push(rscratch1); // cmpptr trashes rscratch1
cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr())); cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
jcc(Assembler::equal, ok); jcc(Assembler::equal, ok);
stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); stop(msg);
bind(ok); bind(ok);
pop(rscratch1); 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 #endif
verify_oop(r, "broken oop in encode_heap_oop"); 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); testq(r, r);
cmovq(Assembler::equal, r, r12_heapbase); cmovq(Assembler::equal, r, r12_heapbase);
subq(r, r12_heapbase); subq(r, r12_heapbase);
...@@ -8288,9 +8299,8 @@ void MacroAssembler::encode_heap_oop(Register r) { ...@@ -8288,9 +8299,8 @@ void MacroAssembler::encode_heap_oop(Register r) {
} }
void MacroAssembler::encode_heap_oop_not_null(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 #ifdef ASSERT
verify_heapbase("MacroAssembler::encode_heap_oop_not_null: heap base corrupted?");
if (CheckCompressedOops) { if (CheckCompressedOops) {
Label ok; Label ok;
testq(r, r); testq(r, r);
...@@ -8310,9 +8320,8 @@ void MacroAssembler::encode_heap_oop_not_null(Register 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) { 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 #ifdef ASSERT
verify_heapbase("MacroAssembler::encode_heap_oop_not_null2: heap base corrupted?");
if (CheckCompressedOops) { if (CheckCompressedOops) {
Label ok; Label ok;
testq(src, src); testq(src, src);
...@@ -8335,40 +8344,21 @@ void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { ...@@ -8335,40 +8344,21 @@ void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
} }
void MacroAssembler::decode_heap_oop(Register r) { void MacroAssembler::decode_heap_oop(Register r) {
assert (UseCompressedOops, "should be compressed"); #ifdef ASSERT
assert (Universe::heap() != NULL, "java heap should be initialized"); verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?");
#endif
if (Universe::narrow_oop_base() == NULL) { if (Universe::narrow_oop_base() == NULL) {
if (Universe::narrow_oop_shift() != 0) { if (Universe::narrow_oop_shift() != 0) {
assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
shlq(r, LogMinObjAlignmentInBytes); shlq(r, LogMinObjAlignmentInBytes);
} }
verify_oop(r, "broken oop in decode_heap_oop"); } else {
return; Label done;
} shlq(r, LogMinObjAlignmentInBytes);
#ifdef ASSERT jccb(Assembler::equal, done);
if (CheckCompressedOops) { addq(r, r12_heapbase);
Label ok; bind(done);
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);
} }
#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"); verify_oop(r, "broken oop in decode_heap_oop");
} }
...@@ -8410,9 +8400,11 @@ void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) { ...@@ -8410,9 +8400,11 @@ void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
addq(dst, r12_heapbase); addq(dst, r12_heapbase);
} }
} }
} else if (dst != src) { } else {
assert (Universe::narrow_oop_base() == NULL, "sanity"); assert (Universe::narrow_oop_base() == NULL, "sanity");
movq(dst, src); if (dst != src) {
movq(dst, src);
}
} }
} }
......
...@@ -1714,6 +1714,9 @@ class MacroAssembler: public Assembler { ...@@ -1714,6 +1714,9 @@ class MacroAssembler: public Assembler {
// if heap base register is used - reinit it with the correct value // if heap base register is used - reinit it with the correct value
void reinit_heapbase(); void reinit_heapbase();
DEBUG_ONLY(void verify_heapbase(const char* msg);)
#endif // _LP64 #endif // _LP64
// Int division/remainder for Java // Int division/remainder for Java
......
...@@ -2442,6 +2442,10 @@ class CommandLineFlags { ...@@ -2442,6 +2442,10 @@ class CommandLineFlags {
"Call fatal if this exception is thrown. Example: " \ "Call fatal if this exception is thrown. Example: " \
"java -XX:AbortVMOnException=java.lang.NullPointerException Foo") \ "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, \ develop(bool, DebugVtables, false, \
"add debugging code to vtable dispatch") \ "add debugging code to vtable dispatch") \
\ \
......
...@@ -117,7 +117,7 @@ void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exc ...@@ -117,7 +117,7 @@ void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exc
(address)h_exception(), file, line, thread); (address)h_exception(), file, line, thread);
} }
// for AbortVMOnException flag // 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 // Check for special boot-strapping/vm-thread handling
if (special_exception(thread, file, line, h_exception)) return; if (special_exception(thread, file, line, h_exception)) return;
...@@ -375,17 +375,26 @@ ExceptionMark::~ExceptionMark() { ...@@ -375,17 +375,26 @@ ExceptionMark::~ExceptionMark() {
#ifndef PRODUCT #ifndef PRODUCT
// caller frees value_string if necessary // 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 && if (AbortVMOnException != NULL && value_string != NULL &&
strstr(value_string, AbortVMOnException)) { 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) { if (AbortVMOnException != NULL) {
ResourceMark rm; 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 #endif
...@@ -143,8 +143,8 @@ class Exceptions { ...@@ -143,8 +143,8 @@ class Exceptions {
static void throw_stack_overflow_exception(Thread* thread, const char* file, int line); static void throw_stack_overflow_exception(Thread* thread, const char* file, int line);
// for AbortVMOnException flag // for AbortVMOnException flag
NOT_PRODUCT(static void debug_check_abort(Handle exception);) NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);)
NOT_PRODUCT(static void debug_check_abort(const char *value_string);) NOT_PRODUCT(static void debug_check_abort(const char *value_string, const char* message = NULL);)
}; };
......
...@@ -479,8 +479,8 @@ void VMError::report(outputStream* st) { ...@@ -479,8 +479,8 @@ void VMError::report(outputStream* st) {
if (fr.sp()) { if (fr.sp()) {
st->print(", sp=" PTR_FORMAT, fr.sp()); st->print(", sp=" PTR_FORMAT, fr.sp());
st->print(", free space=%" INTPTR_FORMAT "k", size_t free_stack_size = pointer_delta(fr.sp(), stack_bottom, 1024);
((intptr_t)fr.sp() - (intptr_t)stack_bottom) >> 10); st->print(", free space=" SIZE_FORMAT "k", free_stack_size);
} }
st->cr(); st->cr();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册