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

Fri, 30 Jul 2010 10:21:15 -0700

author
kvn
date
Fri, 30 Jul 2010 10:21:15 -0700
changeset 2039
66c5dadb4d61
parent 2038
99ceb0e99c9e
child 2040
0e35fa8ebccd

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

src/cpu/x86/vm/assembler_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/assembler_x86.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/exceptions.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/exceptions.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/vmError.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Mon Jul 26 15:58:07 2010 -0700
     1.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Fri Jul 30 10:21:15 2010 -0700
     1.3 @@ -7568,21 +7568,27 @@
     1.4  
     1.5    // Scan RCX words at [RDI] for an occurrence of RAX.
     1.6    // Set NZ/Z based on last compare.
     1.7 +  // Z flag value will not be set by 'repne' if RCX == 0 since 'repne' does
     1.8 +  // not change flags (only scas instruction which is repeated sets flags).
     1.9 +  // Set Z = 0 (not equal) before 'repne' to indicate that class was not found.
    1.10  #ifdef _LP64
    1.11    // This part is tricky, as values in supers array could be 32 or 64 bit wide
    1.12    // and we store values in objArrays always encoded, thus we need to encode
    1.13    // the value of rax before repne.  Note that rax is dead after the repne.
    1.14    if (UseCompressedOops) {
    1.15 -    encode_heap_oop_not_null(rax);
    1.16 +    encode_heap_oop_not_null(rax); // Changes flags.
    1.17      // The superclass is never null; it would be a basic system error if a null
    1.18      // pointer were to sneak in here.  Note that we have already loaded the
    1.19      // Klass::super_check_offset from the super_klass in the fast path,
    1.20      // so if there is a null in that register, we are already in the afterlife.
    1.21 +    testl(rax,rax); // Set Z = 0
    1.22      repne_scanl();
    1.23    } else
    1.24  #endif // _LP64
    1.25 +  {
    1.26 +    testptr(rax,rax); // Set Z = 0
    1.27      repne_scan();
    1.28 -
    1.29 +  }
    1.30    // Unspill the temp. registers:
    1.31    if (pushed_rdi)  pop(rdi);
    1.32    if (pushed_rcx)  pop(rcx);
    1.33 @@ -8257,30 +8263,35 @@
    1.34    }
    1.35  }
    1.36  
    1.37 +#ifdef ASSERT
    1.38 +void MacroAssembler::verify_heapbase(const char* msg) {
    1.39 +  assert (UseCompressedOops, "should be compressed");
    1.40 +  assert (Universe::heap() != NULL, "java heap should be initialized");
    1.41 +  if (CheckCompressedOops) {
    1.42 +    Label ok;
    1.43 +    push(rscratch1); // cmpptr trashes rscratch1
    1.44 +    cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
    1.45 +    jcc(Assembler::equal, ok);
    1.46 +    stop(msg);
    1.47 +    bind(ok);
    1.48 +    pop(rscratch1);
    1.49 +  }
    1.50 +}
    1.51 +#endif
    1.52 +
    1.53  // Algorithm must match oop.inline.hpp encode_heap_oop.
    1.54  void MacroAssembler::encode_heap_oop(Register r) {
    1.55 -  assert (UseCompressedOops, "should be compressed");
    1.56 -  assert (Universe::heap() != NULL, "java heap should be initialized");
    1.57 +#ifdef ASSERT
    1.58 +  verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
    1.59 +#endif
    1.60 +  verify_oop(r, "broken oop in encode_heap_oop");
    1.61    if (Universe::narrow_oop_base() == NULL) {
    1.62 -    verify_oop(r, "broken oop in encode_heap_oop");
    1.63      if (Universe::narrow_oop_shift() != 0) {
    1.64        assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
    1.65        shrq(r, LogMinObjAlignmentInBytes);
    1.66      }
    1.67      return;
    1.68    }
    1.69 -#ifdef ASSERT
    1.70 -  if (CheckCompressedOops) {
    1.71 -    Label ok;
    1.72 -    push(rscratch1); // cmpptr trashes rscratch1
    1.73 -    cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
    1.74 -    jcc(Assembler::equal, ok);
    1.75 -    stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
    1.76 -    bind(ok);
    1.77 -    pop(rscratch1);
    1.78 -  }
    1.79 -#endif
    1.80 -  verify_oop(r, "broken oop in encode_heap_oop");
    1.81    testq(r, r);
    1.82    cmovq(Assembler::equal, r, r12_heapbase);
    1.83    subq(r, r12_heapbase);
    1.84 @@ -8288,9 +8299,8 @@
    1.85  }
    1.86  
    1.87  void MacroAssembler::encode_heap_oop_not_null(Register r) {
    1.88 -  assert (UseCompressedOops, "should be compressed");
    1.89 -  assert (Universe::heap() != NULL, "java heap should be initialized");
    1.90  #ifdef ASSERT
    1.91 +  verify_heapbase("MacroAssembler::encode_heap_oop_not_null: heap base corrupted?");
    1.92    if (CheckCompressedOops) {
    1.93      Label ok;
    1.94      testq(r, r);
    1.95 @@ -8310,9 +8320,8 @@
    1.96  }
    1.97  
    1.98  void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
    1.99 -  assert (UseCompressedOops, "should be compressed");
   1.100 -  assert (Universe::heap() != NULL, "java heap should be initialized");
   1.101  #ifdef ASSERT
   1.102 +  verify_heapbase("MacroAssembler::encode_heap_oop_not_null2: heap base corrupted?");
   1.103    if (CheckCompressedOops) {
   1.104      Label ok;
   1.105      testq(src, src);
   1.106 @@ -8335,40 +8344,21 @@
   1.107  }
   1.108  
   1.109  void  MacroAssembler::decode_heap_oop(Register r) {
   1.110 -  assert (UseCompressedOops, "should be compressed");
   1.111 -  assert (Universe::heap() != NULL, "java heap should be initialized");
   1.112 +#ifdef ASSERT
   1.113 +  verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?");
   1.114 +#endif
   1.115    if (Universe::narrow_oop_base() == NULL) {
   1.116      if (Universe::narrow_oop_shift() != 0) {
   1.117        assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
   1.118        shlq(r, LogMinObjAlignmentInBytes);
   1.119      }
   1.120 -    verify_oop(r, "broken oop in decode_heap_oop");
   1.121 -    return;
   1.122 -  }
   1.123 -#ifdef ASSERT
   1.124 -  if (CheckCompressedOops) {
   1.125 -    Label ok;
   1.126 -    push(rscratch1);
   1.127 -    cmpptr(r12_heapbase,
   1.128 -           ExternalAddress((address)Universe::narrow_oop_base_addr()));
   1.129 -    jcc(Assembler::equal, ok);
   1.130 -    stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
   1.131 -    bind(ok);
   1.132 -    pop(rscratch1);
   1.133 -  }
   1.134 -#endif
   1.135 -
   1.136 -  Label done;
   1.137 -  shlq(r, LogMinObjAlignmentInBytes);
   1.138 -  jccb(Assembler::equal, done);
   1.139 -  addq(r, r12_heapbase);
   1.140 -#if 0
   1.141 -   // alternate decoding probably a wash.
   1.142 -   testq(r, r);
   1.143 -   jccb(Assembler::equal, done);
   1.144 -   leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
   1.145 -#endif
   1.146 -  bind(done);
   1.147 +  } else {
   1.148 +    Label done;
   1.149 +    shlq(r, LogMinObjAlignmentInBytes);
   1.150 +    jccb(Assembler::equal, done);
   1.151 +    addq(r, r12_heapbase);
   1.152 +    bind(done);
   1.153 +  }
   1.154    verify_oop(r, "broken oop in decode_heap_oop");
   1.155  }
   1.156  
   1.157 @@ -8410,9 +8400,11 @@
   1.158          addq(dst, r12_heapbase);
   1.159        }
   1.160      }
   1.161 -  } else if (dst != src) {
   1.162 +  } else {
   1.163      assert (Universe::narrow_oop_base() == NULL, "sanity");
   1.164 -    movq(dst, src);
   1.165 +    if (dst != src) {
   1.166 +      movq(dst, src);
   1.167 +    }
   1.168    }
   1.169  }
   1.170  
     2.1 --- a/src/cpu/x86/vm/assembler_x86.hpp	Mon Jul 26 15:58:07 2010 -0700
     2.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp	Fri Jul 30 10:21:15 2010 -0700
     2.3 @@ -1714,6 +1714,9 @@
     2.4  
     2.5    // if heap base register is used - reinit it with the correct value
     2.6    void reinit_heapbase();
     2.7 +
     2.8 +  DEBUG_ONLY(void verify_heapbase(const char* msg);)
     2.9 +
    2.10  #endif // _LP64
    2.11  
    2.12    // Int division/remainder for Java
     3.1 --- a/src/share/vm/runtime/globals.hpp	Mon Jul 26 15:58:07 2010 -0700
     3.2 +++ b/src/share/vm/runtime/globals.hpp	Fri Jul 30 10:21:15 2010 -0700
     3.3 @@ -2442,6 +2442,10 @@
     3.4            "Call fatal if this exception is thrown.  Example: "              \
     3.5            "java -XX:AbortVMOnException=java.lang.NullPointerException Foo") \
     3.6                                                                              \
     3.7 +  notproduct(ccstr, AbortVMOnExceptionMessage, NULL,                        \
     3.8 +          "Call fatal if the exception pointed by AbortVMOnException "      \
     3.9 +          "has this message.")                                              \
    3.10 +                                                                            \
    3.11    develop(bool, DebugVtables, false,                                        \
    3.12            "add debugging code to vtable dispatch")                          \
    3.13                                                                              \
     4.1 --- a/src/share/vm/utilities/exceptions.cpp	Mon Jul 26 15:58:07 2010 -0700
     4.2 +++ b/src/share/vm/utilities/exceptions.cpp	Fri Jul 30 10:21:15 2010 -0700
     4.3 @@ -117,7 +117,7 @@
     4.4                    (address)h_exception(), file, line, thread);
     4.5    }
     4.6    // for AbortVMOnException flag
     4.7 -  NOT_PRODUCT(Exceptions::debug_check_abort(h_exception));
     4.8 +  NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message));
     4.9  
    4.10    // Check for special boot-strapping/vm-thread handling
    4.11    if (special_exception(thread, file, line, h_exception)) return;
    4.12 @@ -375,17 +375,26 @@
    4.13  
    4.14  #ifndef PRODUCT
    4.15  // caller frees value_string if necessary
    4.16 -void Exceptions::debug_check_abort(const char *value_string) {
    4.17 +void Exceptions::debug_check_abort(const char *value_string, const char* message) {
    4.18    if (AbortVMOnException != NULL && value_string != NULL &&
    4.19        strstr(value_string, AbortVMOnException)) {
    4.20 -    fatal(err_msg("Saw %s, aborting", value_string));
    4.21 +    if (AbortVMOnExceptionMessage == NULL || message == NULL ||
    4.22 +        strcmp(message, AbortVMOnExceptionMessage) == 0) {
    4.23 +      fatal(err_msg("Saw %s, aborting", value_string));
    4.24 +    }
    4.25    }
    4.26  }
    4.27  
    4.28 -void Exceptions::debug_check_abort(Handle exception) {
    4.29 +void Exceptions::debug_check_abort(Handle exception, const char* message) {
    4.30    if (AbortVMOnException != NULL) {
    4.31      ResourceMark rm;
    4.32 -    debug_check_abort(instanceKlass::cast(exception()->klass())->external_name());
    4.33 +    if (message == NULL && exception->is_a(SystemDictionary::Throwable_klass())) {
    4.34 +      oop msg = java_lang_Throwable::message(exception);
    4.35 +      if (msg != NULL) {
    4.36 +        message = java_lang_String::as_utf8_string(msg);
    4.37 +      }
    4.38 +    }
    4.39 +    debug_check_abort(instanceKlass::cast(exception()->klass())->external_name(), message);
    4.40    }
    4.41  }
    4.42  #endif
     5.1 --- a/src/share/vm/utilities/exceptions.hpp	Mon Jul 26 15:58:07 2010 -0700
     5.2 +++ b/src/share/vm/utilities/exceptions.hpp	Fri Jul 30 10:21:15 2010 -0700
     5.3 @@ -143,8 +143,8 @@
     5.4    static void throw_stack_overflow_exception(Thread* thread, const char* file, int line);
     5.5  
     5.6    // for AbortVMOnException flag
     5.7 -  NOT_PRODUCT(static void debug_check_abort(Handle exception);)
     5.8 -  NOT_PRODUCT(static void debug_check_abort(const char *value_string);)
     5.9 +  NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);)
    5.10 +  NOT_PRODUCT(static void debug_check_abort(const char *value_string, const char* message = NULL);)
    5.11  };
    5.12  
    5.13  
     6.1 --- a/src/share/vm/utilities/vmError.cpp	Mon Jul 26 15:58:07 2010 -0700
     6.2 +++ b/src/share/vm/utilities/vmError.cpp	Fri Jul 30 10:21:15 2010 -0700
     6.3 @@ -479,8 +479,8 @@
     6.4  
     6.5         if (fr.sp()) {
     6.6           st->print(",  sp=" PTR_FORMAT, fr.sp());
     6.7 -         st->print(",  free space=%" INTPTR_FORMAT "k",
     6.8 -                     ((intptr_t)fr.sp() - (intptr_t)stack_bottom) >> 10);
     6.9 +         size_t free_stack_size = pointer_delta(fr.sp(), stack_bottom, 1024);
    6.10 +         st->print(",  free space=" SIZE_FORMAT "k", free_stack_size);
    6.11         }
    6.12  
    6.13         st->cr();

mercurial