# HG changeset patch # User jmasa # Date 1229717734 28800 # Node ID 4632ed70b87439a1b6175dcac88f95e30264224e # Parent 93ac4ec3f0e8e4bedaedc03e267d32c591c3f49d# Parent 56dd12dd6cb3028187cfe82b12b365405caec7dc Merge diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/.hgtags --- a/hotspot/.hgtags Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/.hgtags Fri Dec 19 12:15:34 2008 -0800 @@ -15,3 +15,4 @@ d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38 49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39 81a0cbe3b28460ce836109934ece03db7afaf9cc jdk7-b40 +f9d938ede1960d18cb7cf23c645b026519c1a678 jdk7-b41 diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/make/hotspot_version --- a/hotspot/make/hotspot_version Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/make/hotspot_version Fri Dec 19 12:15:34 2008 -0800 @@ -35,7 +35,7 @@ HS_MAJOR_VER=14 HS_MINOR_VER=0 -HS_BUILD_NUMBER=08 +HS_BUILD_NUMBER=09 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/make/linux/adlc_updater --- a/hotspot/make/linux/adlc_updater Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/make/linux/adlc_updater Fri Dec 19 12:15:34 2008 -0800 @@ -7,5 +7,13 @@ # # adlc-updater # -[ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \ -( [ -f $3/$1 ]; echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 ) +fix_lines() { + # repair bare #line directives in $1 to refer to $2 + awk < $1 > $1+ ' + /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next} + {print} + ' F2=$2 + mv $1+ $1 +} +[ -f $3/$1 ] && (fix_lines $2/$1 $3/$1; cmp -s $2/$1 $3/$1) || \ +( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 ) diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/make/linux/makefiles/adlc.make --- a/hotspot/make/linux/makefiles/adlc.make Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/make/linux/makefiles/adlc.make Fri Dec 19 12:15:34 2008 -0800 @@ -54,9 +54,11 @@ Src_Dirs_I = ${Src_Dirs} $(GENERATED) INCLUDES += $(Src_Dirs_I:%=-I%) +# set flags for adlc compilation +CPPFLAGS = $(SYSDEFS) $(INCLUDES) + # Force assertions on. -SYSDEFS += -DASSERT -CPPFLAGS = $(SYSDEFS) $(INCLUDES) +CPPFLAGS += -DASSERT # CFLAGS_WARN holds compiler options to suppress/enable warnings. # Suppress warnings (for now) @@ -125,7 +127,15 @@ # Note that product files are updated via "mv", which is atomic. TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$) -ADLCFLAGS = -q -T +# Pass -D flags into ADLC. +ADLCFLAGS += $(SYSDEFS) + +# Note "+="; it is a hook so flags.make can add more flags, like -g or -DFOO. +ADLCFLAGS += -q -T + +# Normally, debugging is done directly on the ad_*.cpp files. +# But -g will put #line directives in those files pointing back to .ad. +#ADLCFLAGS += -g ifdef LP64 ADLCFLAGS += -D_LP64 @@ -140,6 +150,8 @@ # ADLC_UPDATER_DIRECTORY = $(GAMMADIR)/make/$(OS) ADLC_UPDATER = adlc_updater +$(ADLC_UPDATER): $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) + $(QUIETLY) cp $< $@; chmod +x $@ # This action refreshes all generated adlc files simultaneously. # The way it works is this: @@ -149,9 +161,8 @@ # 4) call $(ADLC_UPDATER) on each generated adlc file. It will selectively update changed or missing files. # 5) If we actually updated any files, echo a notice. # -refresh_adfiles: $(EXEC) $(SOURCE.AD) +refresh_adfiles: $(EXEC) $(SOURCE.AD) $(ADLC_UPDATER) @rm -rf $(TEMPDIR); mkdir $(TEMPDIR) - $(QUIETLY) [ -f $(ADLC_UPDATER) ] || ( cp $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) . ; chmod +x $(ADLC_UPDATER) ) $(QUIETLY) $(EXEC) $(ADLCFLAGS) $(SOURCE.AD) \ -c$(TEMPDIR)/ad_$(Platform_arch_model).cpp -h$(TEMPDIR)/ad_$(Platform_arch_model).hpp -a$(TEMPDIR)/dfa_$(Platform_arch_model).cpp -v$(TEMPDIR)/adGlobals_$(Platform_arch_model).hpp \ || { rm -rf $(TEMPDIR); exit 1; } @@ -174,7 +185,15 @@ # ######################################################################### $(SOURCE.AD): $(SOURCES.AD) - $(QUIETLY) cat $(SOURCES.AD) > $(SOURCE.AD) + $(QUIETLY) $(PROCESS_AD_FILES) $(SOURCES.AD) > $(SOURCE.AD) + +#PROCESS_AD_FILES = cat +# Pass through #line directives, in case user enables -g option above: +PROCESS_AD_FILES = awk '{ \ + if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \ + if (need_lineno && $$0 !~ /\/\//) \ + { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \ + print }' $(OUTDIR)/%.o: %.cpp @echo Compiling $< diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/make/solaris/adlc_updater --- a/hotspot/make/solaris/adlc_updater Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/make/solaris/adlc_updater Fri Dec 19 12:15:34 2008 -0800 @@ -7,5 +7,13 @@ # # adlc-updater # -[ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \ -( [ -f $3/$1 ]; echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 ) +fix_lines() { + # repair bare #line directives in $1 to refer to $2 + awk < $1 > $1+ ' + /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next} + {print} + ' F2=$2 + mv $1+ $1 +} +[ -f $3/$1 ] && (fix_lines $2/$1 $3/$1; cmp -s $2/$1 $3/$1) || \ +( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 ) diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/make/solaris/makefiles/adlc.make --- a/hotspot/make/solaris/makefiles/adlc.make Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/make/solaris/makefiles/adlc.make Fri Dec 19 12:15:34 2008 -0800 @@ -54,9 +54,11 @@ Src_Dirs_I = ${Src_Dirs} $(GENERATED) INCLUDES += $(Src_Dirs_I:%=-I%) +# set flags for adlc compilation +CPPFLAGS = $(SYSDEFS) $(INCLUDES) + # Force assertions on. -SYSDEFS += -DASSERT -CPPFLAGS = $(SYSDEFS) $(INCLUDES) +CPPFLAGS += -DASSERT ifndef USE_GCC # We need libCstd.so for adlc @@ -141,7 +143,15 @@ # Note that product files are updated via "mv", which is atomic. TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$) -ADLCFLAGS = -q -T +# Pass -D flags into ADLC. +ADLCFLAGS += $(SYSDEFS) + +# Note "+="; it is a hook so flags.make can add more flags, like -g or -DFOO. +ADLCFLAGS += -q -T + +# Normally, debugging is done directly on the ad_*.cpp files. +# But -g will put #line directives in those files pointing back to .ad. +#ADLCFLAGS += -g ifdef LP64 ADLCFLAGS += -D_LP64 @@ -156,6 +166,8 @@ # ADLC_UPDATER_DIRECTORY = $(GAMMADIR)/make/$(OS) ADLC_UPDATER = adlc_updater +$(ADLC_UPDATER): $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) + $(QUIETLY) cp $< $@; chmod +x $@ # This action refreshes all generated adlc files simultaneously. # The way it works is this: @@ -165,9 +177,8 @@ # 4) call $(ADLC_UPDATER) on each generated adlc file. It will selectively update changed or missing files. # 5) If we actually updated any files, echo a notice. # -refresh_adfiles: $(EXEC) $(SOURCE.AD) +refresh_adfiles: $(EXEC) $(SOURCE.AD) $(ADLC_UPDATER) @rm -rf $(TEMPDIR); mkdir $(TEMPDIR) - $(QUIETLY) [ -f $(ADLC_UPDATER) ] || ( cp $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER) . ; chmod +x $(ADLC_UPDATER) ) $(QUIETLY) $(EXEC) $(ADLCFLAGS) $(SOURCE.AD) \ -c$(TEMPDIR)/ad_$(Platform_arch_model).cpp -h$(TEMPDIR)/ad_$(Platform_arch_model).hpp -a$(TEMPDIR)/dfa_$(Platform_arch_model).cpp -v$(TEMPDIR)/adGlobals_$(Platform_arch_model).hpp \ || { rm -rf $(TEMPDIR); exit 1; } @@ -190,7 +201,15 @@ # ######################################################################### $(SOURCE.AD): $(SOURCES.AD) - $(QUIETLY) cat $(SOURCES.AD) > $(SOURCE.AD) + $(QUIETLY) $(PROCESS_AD_FILES) $(SOURCES.AD) > $(SOURCE.AD) + +#PROCESS_AD_FILES = cat +# Pass through #line directives, in case user enables -g option above: +PROCESS_AD_FILES = awk '{ \ + if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \ + if (need_lineno && $$0 !~ /\/\//) \ + { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \ + print }' $(OUTDIR)/%.o: %.cpp @echo Compiling $< diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -2500,7 +2500,7 @@ } bool os::unguard_memory(char* addr, size_t size) { - return linux_mprotect(addr, size, PROT_READ|PROT_WRITE|PROT_EXEC); + return linux_mprotect(addr, size, PROT_READ|PROT_WRITE); } // Large page support diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -3026,6 +3026,8 @@ // Protect memory (Used to pass readonly pages through // JNI GetArrayElements with empty arrays.) +// Also, used for serialization page and for compressed oops null pointer +// checking. bool os::protect_memory(char* addr, size_t bytes, ProtType prot, bool is_committed) { unsigned int p = 0; @@ -3049,7 +3051,7 @@ } bool os::unguard_memory(char* addr, size_t bytes) { - return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE|PROT_EXEC); + return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE); } // Large page support diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -2020,10 +2020,11 @@ if (UnguardOnExecutionViolation > 0 && addr != last_addr && (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) { - // Unguard and retry + // Set memory to RWX and retry address page_start = (address) align_size_down((intptr_t) addr, (intptr_t) page_size); - bool res = os::unguard_memory((char*) page_start, page_size); + bool res = os::protect_memory((char*) page_start, page_size, + os::MEM_PROT_RWX); if (PrintMiscellaneous && Verbose) { char buf[256]; @@ -2217,15 +2218,10 @@ // We only expect null pointers in the stubs (vtable) // the rest are checked explicitly now. // - CodeBlob* cb = CodeCache::find_blob(pc); - if (cb != NULL) { - if (VtableStubs::stub_containing(pc) != NULL) { - if (((uintptr_t)addr) < os::vm_page_size() ) { - // an access to the first page of VM--assume it is a null pointer - return Handle_Exception(exceptionInfo, - SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL)); - } - } + if (((uintptr_t)addr) < os::vm_page_size() ) { + // an access to the first page of VM--assume it is a null pointer + address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); + if (stub != NULL) return Handle_Exception(exceptionInfo, stub); } } } // in_java @@ -2241,9 +2237,8 @@ // Windows 98 reports faulting addresses incorrectly if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) || !os::win32::is_nt()) { - - return Handle_Exception(exceptionInfo, - SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL)); + address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); + if (stub != NULL) return Handle_Exception(exceptionInfo, stub); } report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, exceptionInfo->ContextRecord); @@ -2761,12 +2756,12 @@ bool os::guard_memory(char* addr, size_t bytes) { DWORD old_status; - return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &old_status) != 0; + return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0; } bool os::unguard_memory(char* addr, size_t bytes) { DWORD old_status; - return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &old_status) != 0; + return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0; } void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { } diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -422,10 +422,11 @@ if (addr != last_addr && (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) { - // Unguard and retry + // Set memory to RWX and retry address page_start = (address) align_size_down((intptr_t) addr, (intptr_t) page_size); - bool res = os::unguard_memory((char*) page_start, page_size); + bool res = os::protect_memory((char*) page_start, page_size, + os::MEM_PROT_RWX); if (PrintMiscellaneous && Verbose) { char buf[256]; diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -203,10 +203,10 @@ return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); } -extern "C" intptr_t *_get_previous_fp(); // in .il file. +extern "C" intptr_t *_get_current_fp(); // in .il file frame os::current_frame() { - intptr_t* fp = _get_previous_fp(); + intptr_t* fp = _get_current_fp(); // it's inlined so want current fp frame myframe((intptr_t*)os::current_stack_pointer(), (intptr_t*)fp, CAST_FROM_FN_PTR(address, os::current_frame)); @@ -576,10 +576,11 @@ if (addr != last_addr && (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) { - // Unguard and retry + // Make memory rwx and retry address page_start = (address) align_size_down((intptr_t) addr, (intptr_t) page_size); - bool res = os::unguard_memory((char*) page_start, page_size); + bool res = os::protect_memory((char*) page_start, page_size, + os::MEM_PROT_RWX); if (PrintMiscellaneous && Verbose) { char buf[256]; diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il Fri Dec 19 12:15:34 2008 -0800 @@ -37,10 +37,10 @@ movl %gs:0, %eax .end - // Get callers fp - .inline _get_previous_fp,0 + // Get current fp + .inline _get_current_fp,0 + .volatile movl %ebp, %eax - movl %eax, %eax .end // Support for jint Atomic::add(jint inc, volatile jint* dest) diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il Fri Dec 19 12:15:34 2008 -0800 @@ -30,10 +30,10 @@ movq %fs:0, %rax .end - // Get the frame pointer from previous frame. - .inline _get_previous_fp,0 + // Get the frame pointer from current frame. + .inline _get_current_fp,0 + .volatile movq %rbp, %rax - movq %rax, %rax .end // Support for jint Atomic::add(jint add_value, volatile jint* dest) diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/adlc/adlparse.cpp --- a/hotspot/src/share/vm/adlc/adlparse.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/adlc/adlparse.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -108,6 +108,7 @@ else if (!strcmp(ident, "pipeline")) pipe_parse(); else if (!strcmp(ident, "definitions")) definitions_parse(); else if (!strcmp(ident, "peephole")) peep_parse(); + else if (!strcmp(ident, "#line")) preproc_line(); else if (!strcmp(ident, "#define")) preproc_define(); else if (!strcmp(ident, "#undef")) preproc_undef(); else { @@ -786,9 +787,11 @@ parse_err(SYNERR, "missing identifier inside register block.\n"); return; } - if (strcmp(token,"reg_def")==0) { reg_def_parse(); } - if (strcmp(token,"reg_class")==0) { reg_class_parse(); } - if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); } + if (strcmp(token,"reg_def")==0) { reg_def_parse(); } + else if (strcmp(token,"reg_class")==0) { reg_class_parse(); } + else if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); } + else if (strcmp(token,"#define")==0) { preproc_define(); } + else { parse_err(SYNERR, "bad token %s inside register block.\n", token); break; } skipws(); } } @@ -903,11 +906,7 @@ skipws_no_preproc(); // Skip leading whitespace // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block if (_AD._adlocation_debug) { - const char* file = _AD._ADL_file._name; - int line = linenum(); - char* location = (char *)malloc(strlen(file) + 100); - sprintf(location, "#line %d \"%s\"\n", line, file); - encoding->add_code(location); + encoding->add_code(get_line_string()); } // Collect the parts of the encode description @@ -948,6 +947,10 @@ skipws(); + if (_AD._adlocation_debug) { + encoding->add_code(end_line_marker()); + } + // Debug Stuff if (_AD._adl_debug > 1) fprintf(stderr,"EncodingClass Form: %s\n", ec_name); } @@ -2349,7 +2352,11 @@ return; } RegDef *regDef = _AD._register->getRegDef(rname); - reg_class->addReg(regDef); // add regDef to regClass + if (!regDef) { + parse_err(SEMERR, "unknown identifier %s inside reg_class list.\n", rname); + } else { + reg_class->addReg(regDef); // add regDef to regClass + } // Check for ',' and position to next token. skipws(); @@ -2746,7 +2753,8 @@ char *rule = NULL; // String representation of predicate skipws(); // Skip leading whitespace - if ( (rule = get_paren_expr("pred expression")) == NULL ) { + int line = linenum(); + if ( (rule = get_paren_expr("pred expression", true)) == NULL ) { parse_err(SYNERR, "incorrect or missing expression for 'predicate'\n"); return NULL; } @@ -3407,7 +3415,12 @@ // Check if there is a string to pass through to output char *start = _ptr; // Record start of the next string while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) { - if (_curchar == '\\') next_char(); // superquote + if (_curchar == '\\') { + next_char(); // superquote + if ((_curchar == '$') || (_curchar == '%')) + // hack to avoid % escapes and warnings about undefined \ escapes + *(_ptr-1) = _curchar; + } if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented! next_char(); } @@ -3942,8 +3955,7 @@ next_char(); // Skip block delimiter skipws_no_preproc(); // Skip leading whitespace cppBlock = _ptr; // Point to start of expression - const char* file = _AD._ADL_file._name; - int line = linenum(); + int line = linenum(); next = _ptr + 1; while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) { next_char_or_line(); @@ -3958,15 +3970,16 @@ _curchar = *_ptr; // Maintain invariant // Prepend location descriptor, for debugging. - char* location = (char *)malloc(strlen(file) + 100); - *location = '\0'; - if (_AD._adlocation_debug) - sprintf(location, "#line %d \"%s\"\n", line, file); - char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + 1); - strcpy(result, location); - strcat(result, cppBlock); - cppBlock = result; - free(location); + if (_AD._adlocation_debug) { + char* location = get_line_string(line); + char* end_loc = end_line_marker(); + char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + strlen(end_loc) + 1); + strcpy(result, location); + strcat(result, cppBlock); + strcat(result, end_loc); + cppBlock = result; + free(location); + } } return cppBlock; @@ -4036,13 +4049,26 @@ // Helper function around get_expr // Sets _curchar to '(' so that get_paren_expr will search for a matching ')' -char *ADLParser::get_paren_expr(const char *description) { +char *ADLParser::get_paren_expr(const char *description, bool include_location) { + int line = linenum(); if (_curchar != '(') // Escape if not valid starting position return NULL; next_char(); // Skip the required initial paren. char *token2 = get_expr(description, ")"); if (_curchar == ')') next_char(); // Skip required final paren. + int junk = 0; + if (include_location && _AD._adlocation_debug && !is_int_token(token2, junk)) { + // Prepend location descriptor, for debugging. + char* location = get_line_string(line); + char* end_loc = end_line_marker(); + char* result = (char *)malloc(strlen(location) + strlen(token2) + strlen(end_loc) + 1); + strcpy(result, location); + strcat(result, token2); + strcat(result, end_loc); + token2 = result; + free(location); + } return token2; } @@ -4082,10 +4108,16 @@ if (do_preproc && start != NULL) { const char* def = _AD.get_preproc_def(start); if (def != NULL && strcmp(def, start)) { - const char* def2 = _AD.get_preproc_def(def); - if (def2 != NULL && strcmp(def2, def)) { - parse_err(SYNERR, "unimplemented: using %s defined as %s => %s", - start, def, def2); + const char* def1 = def; + const char* def2 = _AD.get_preproc_def(def1); + // implement up to 2 levels of #define + if (def2 != NULL && strcmp(def2, def1)) { + def = def2; + const char* def3 = _AD.get_preproc_def(def2); + if (def3 != NULL && strcmp(def3, def2) && strcmp(def3, def1)) { + parse_err(SYNERR, "unimplemented: using %s defined as %s => %s => %s", + start, def1, def2, def3); + } } start = strdup(def); } @@ -4431,6 +4463,35 @@ } +//-------------------------------preproc_line---------------------------------- +// A "#line" keyword has been seen, so parse the rest of the line. +void ADLParser::preproc_line(void) { + int line = get_int(); + skipws_no_preproc(); + const char* file = NULL; + if (_curchar == '"') { + next_char(); // Move past the initial '"' + file = _ptr; + while (true) { + if (_curchar == '\n') { + parse_err(SYNERR, "missing '\"' at end of #line directive"); + return; + } + if (_curchar == '"') { + *_ptr = '\0'; // Terminate the string + next_char(); + skipws_no_preproc(); + break; + } + next_char(); + } + } + ensure_end_of_line(); + if (file != NULL) + _AD._ADL_file._name = file; + _buf.set_linenum(line); +} + //------------------------------preproc_define--------------------------------- // A "#define" keyword has been seen, so parse the rest of the line. void ADLParser::preproc_define(void) { @@ -4494,6 +4555,7 @@ // A preprocessor directive has been encountered. Be sure it has fallen at // the begining of a line, or else report an error. void ADLParser::ensure_start_of_line(void) { + if (_curchar == '\n') { next_line(); return; } assert( _ptr >= _curline && _ptr < _curline+strlen(_curline), "Must be able to find which line we are in" ); @@ -4662,6 +4724,7 @@ //---------------------------next_char----------------------------------------- void ADLParser::next_char() { + if (_curchar == '\n') parse_err(WARN, "must call next_line!"); _curchar = *++_ptr; // if ( _curchar == '\n' ) { // next_line(); @@ -4682,6 +4745,18 @@ //---------------------------next_line----------------------------------------- void ADLParser::next_line() { _curline = _buf.get_line(); + _curchar = ' '; +} + +//------------------------get_line_string-------------------------------------- +// Prepended location descriptor, for debugging. +// Must return a malloced string (that can be freed if desired). +char* ADLParser::get_line_string(int linenum) { + const char* file = _AD._ADL_file._name; + int line = linenum ? linenum : this->linenum(); + char* location = (char *)malloc(strlen(file) + 100); + sprintf(location, "\n#line %d \"%s\"\n", line, file); + return location; } //-------------------------is_literal_constant--------------------------------- @@ -4722,6 +4797,66 @@ return true; } +static const char* skip_expr_ws(const char* str) { + const char * cp = str; + while (cp[0]) { + if (cp[0] <= ' ') { + ++cp; + } else if (cp[0] == '#') { + ++cp; + while (cp[0] == ' ') ++cp; + assert(0 == strncmp(cp, "line", 4), "must be a #line directive"); + const char* eol = strchr(cp, '\n'); + assert(eol != NULL, "must find end of line"); + if (eol == NULL) eol = cp + strlen(cp); + cp = eol; + } else { + break; + } + } + return cp; +} + +//-----------------------equivalent_expressions-------------------------------- +bool ADLParser::equivalent_expressions(const char* str1, const char* str2) { + if (str1 == str2) + return true; + else if (str1 == NULL || str2 == NULL) + return false; + const char* cp1 = str1; + const char* cp2 = str2; + char in_quote = '\0'; + while (cp1[0] && cp2[0]) { + if (!in_quote) { + // skip spaces and/or cpp directives + const char* cp1a = skip_expr_ws(cp1); + const char* cp2a = skip_expr_ws(cp2); + if (cp1a > cp1 && cp2a > cp2) { + cp1 = cp1a; cp2 = cp2a; + continue; + } + if (cp1a > cp1 || cp2a > cp2) break; // fail + } + // match one non-space char + if (cp1[0] != cp2[0]) break; // fail + char ch = cp1[0]; + cp1++; cp2++; + // watch for quotes + if (in_quote && ch == '\\') { + if (cp1[0] != cp2[0]) break; // fail + if (!cp1[0]) break; + cp1++; cp2++; + } + if (in_quote && ch == in_quote) { + in_quote = '\0'; + } else if (!in_quote && (ch == '"' || ch == '\'')) { + in_quote = ch; + } + } + return (!cp1[0] && !cp2[0]); +} + + //-------------------------------trim------------------------------------------ void ADLParser::trim(char* &token) { while (*token <= ' ') token++; diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/adlc/adlparse.hpp --- a/hotspot/src/share/vm/adlc/adlparse.hpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/adlc/adlparse.hpp Fri Dec 19 12:15:34 2008 -0800 @@ -93,6 +93,7 @@ void pipe_parse(void); // Parse pipeline section void definitions_parse(void); // Parse definitions section void peep_parse(void); // Parse peephole rule definitions + void preproc_line(void); // Parse a #line statement void preproc_define(void); // Parse a #define statement void preproc_undef(void); // Parse an #undef statement @@ -226,7 +227,7 @@ void get_effectlist(FormDict &effects, FormDict &operands); // Parse effect-operand pairs // Return the contents of a parenthesized expression. // Requires initial '(' and consumes final ')', which is replaced by '\0'. - char *get_paren_expr(const char *description); + char *get_paren_expr(const char *description, bool include_location = false); // Return expression up to next stop-char, which terminator replaces. // Does not require initial '('. Does not consume final stop-char. // Final stop-char is left in _curchar, but is also is replaced by '\0'. @@ -234,6 +235,11 @@ char *find_cpp_block(const char *description); // Parse a C++ code block // Issue parser error message & go to EOL void parse_err(int flag, const char *fmt, ...); + // Create a location marker for this file and line. + char *get_line_string(int linenum = 0); + // Return a location marker which tells the C preprocessor to + // forget the previous location marker. (Requires awk postprocessing.) + char *end_line_marker() { return (char*)"\n#line 999999\n"; } // Return pointer to current character inline char cur_char(void); @@ -268,5 +274,6 @@ static bool is_literal_constant(const char *hex_string); static bool is_hex_digit(char digit); static bool is_int_token(const char* token, int& intval); + static bool equivalent_expressions(const char* str1, const char* str2); static void trim(char* &token); // trim leading & trailing spaces }; diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/adlc/archDesc.cpp --- a/hotspot/src/share/vm/adlc/archDesc.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/adlc/archDesc.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -140,7 +140,7 @@ if ((rch == _rchild) || (rch && _rchild && !strcmp(rch, _rchild))) { char * predStr = get_pred(); char * prStr = pr?pr->_pred:NULL; - if ((prStr == predStr) || (prStr && predStr && !strcmp(prStr, predStr))) { + if (ADLParser::equivalent_expressions(prStr, predStr)) { return true; } } diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/adlc/dfa.cpp --- a/hotspot/src/share/vm/adlc/dfa.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/adlc/dfa.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -458,7 +458,7 @@ class dfa_shared_preds { - enum { count = 2 }; + enum { count = 4 }; static bool _found[count]; static const char* _type [count]; @@ -479,12 +479,15 @@ char c = *prev; switch( c ) { case ' ': + case '\n': return dfa_shared_preds::valid_loc(pred, prev); case '!': case '(': case '<': case '=': return true; + case '"': // such as: #line 10 "myfile.ad"\n mypredicate + return true; case '|': if( prev != pred && *(prev-1) == '|' ) return true; case '&': @@ -564,10 +567,14 @@ } }; // shared predicates, _var and _pred entry should be the same length -bool dfa_shared_preds::_found[dfa_shared_preds::count] = { false, false }; -const char* dfa_shared_preds::_type[dfa_shared_preds::count] = { "int", "bool" }; -const char* dfa_shared_preds::_var [dfa_shared_preds::count] = { "_n_get_int__", "Compile__current____select_24_bit_instr__" }; -const char* dfa_shared_preds::_pred[dfa_shared_preds::count] = { "n->get_int()", "Compile::current()->select_24_bit_instr()" }; +bool dfa_shared_preds::_found[dfa_shared_preds::count] + = { false, false, false, false }; +const char* dfa_shared_preds::_type[dfa_shared_preds::count] + = { "int", "jlong", "intptr_t", "bool" }; +const char* dfa_shared_preds::_var [dfa_shared_preds::count] + = { "_n_get_int__", "_n_get_long__", "_n_get_intptr_t__", "Compile__current____select_24_bit_instr__" }; +const char* dfa_shared_preds::_pred[dfa_shared_preds::count] + = { "n->get_int()", "n->get_long()", "n->get_intptr_t()", "Compile::current()->select_24_bit_instr()" }; void ArchDesc::gen_dfa_state_body(FILE* fp, Dict &minimize, ProductionState &status, Dict &operands_chained_from, int i) { diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/adlc/filebuff.hpp --- a/hotspot/src/share/vm/adlc/filebuff.hpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/adlc/filebuff.hpp Fri Dec 19 12:15:34 2008 -0800 @@ -68,6 +68,7 @@ // and increments bufeol and filepos to point at the end of that line. char *get_line(void); int linenum() const { return _linenum; } + void set_linenum(int line) { _linenum = line; } // This converts a pointer into the buffer to a file offset. It only works // when the pointer is valid (i.e. just obtained from getline()). diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/adlc/formssel.cpp --- a/hotspot/src/share/vm/adlc/formssel.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/adlc/formssel.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -1102,10 +1102,7 @@ } if( pred1 != NULL && pred2 != NULL ) { // compare the predicates - const char *str1 = pred1->_pred; - const char *str2 = pred2->_pred; - if( (str1 == NULL && str2 == NULL) - || (str1 != NULL && str2 != NULL && strcmp(str1,str2) == 0) ) { + if (ADLParser::equivalent_expressions(pred1->_pred, pred2->_pred)) { return true; } } diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -1210,8 +1210,8 @@ break; case T_LONG: case T_DOUBLE: - if (c->as_jint_hi_bits() != other->as_jint_lo_bits()) continue; - if (c->as_jint_lo_bits() != other->as_jint_hi_bits()) continue; + if (c->as_jint_hi_bits() != other->as_jint_hi_bits()) continue; + if (c->as_jint_lo_bits() != other->as_jint_lo_bits()) continue; break; case T_OBJECT: if (c->as_jobject() != other->as_jobject()) continue; diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/c1/c1_Optimizer.cpp --- a/hotspot/src/share/vm/c1/c1_Optimizer.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/c1/c1_Optimizer.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -327,8 +327,6 @@ BlockBegin* fsux = if_->fsux(); if (swapped) { cond = Instruction::mirror(cond); - tsux = if_->fsux(); - fsux = if_->tsux(); } BlockBegin* tblock = tval->compare(cond, con, tsux, fsux); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/c1/c1_Runtime1.cpp --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -842,6 +842,13 @@ if (TracePatching) { tty->print_cr("Deoptimizing for patching volatile field reference"); } + // It's possible the nmethod was invalidated in the last + // safepoint, but if it's still alive then make it not_entrant. + nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); + if (nm != NULL) { + nm->make_not_entrant(); + } + VM_DeoptimizeFrame deopt(thread, caller_frame.id()); VMThread::execute(&deopt); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -581,7 +581,8 @@ interf = KlassHandle(THREAD, k); vmtimer->resume(); - cp->klass_at_put(interface_index, interf()); // eagerly resolve + if (LinkWellKnownClasses) // my super type is well known to me + cp->klass_at_put(interface_index, interf()); // eagerly resolve } if (!Klass::cast(interf())->is_interface()) { @@ -2699,7 +2700,8 @@ CHECK_(nullHandle)); KlassHandle kh (THREAD, k); super_klass = instanceKlassHandle(THREAD, kh()); - cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve + if (LinkWellKnownClasses) // my super class is well known to me + cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve } if (super_klass.not_null()) { if (super_klass->is_interface()) { @@ -3128,7 +3130,8 @@ this_klass->set_method_ordering(method_ordering()); this_klass->set_initial_method_idnum(methods->length()); this_klass->set_name(cp->klass_name_at(this_class_index)); - cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve + if (LinkWellKnownClasses) // I am well known to myself + cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve this_klass->set_protection_domain(protection_domain()); this_klass->set_fields_annotations(fields_annotations()); this_klass->set_methods_annotations(methods_annotations()); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -181,7 +181,7 @@ void scrub(CardTableModRefBS* ctbs, BitMap* card_bm) { HeapWord* hr_bot = hr()->bottom(); - int hr_first_card_index = ctbs->index_for(hr_bot); + size_t hr_first_card_index = ctbs->index_for(hr_bot); bm()->set_intersection_at_offset(*card_bm, hr_first_card_index); #if PRT_COUNT_OCCUPIED recount_occupied(); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/includeDB_core --- a/hotspot/src/share/vm/includeDB_core Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/includeDB_core Fri Dec 19 12:15:34 2008 -0800 @@ -2303,6 +2303,7 @@ javaCalls.cpp interfaceSupport.hpp javaCalls.cpp interpreter.hpp javaCalls.cpp javaCalls.hpp +javaCalls.cpp jniCheck.hpp javaCalls.cpp linkResolver.hpp javaCalls.cpp mutexLocker.hpp javaCalls.cpp nmethod.hpp diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/includeDB_features --- a/hotspot/src/share/vm/includeDB_features Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/includeDB_features Fri Dec 19 12:15:34 2008 -0800 @@ -115,6 +115,8 @@ heapInspection.cpp os.hpp heapInspection.cpp resourceArea.hpp +javaCalls.cpp jniCheck.hpp + jniCheck.cpp fieldDescriptor.hpp jniCheck.cpp handles.hpp jniCheck.cpp instanceKlass.hpp diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/memory/cardTableModRefBS.cpp --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -283,7 +283,7 @@ } else { entry = byte_after(old_region.last()); } - assert(index_for(new_region.last()) < (int) _guard_index, + assert(index_for(new_region.last()) < _guard_index, "The guard card will be overwritten"); // This line commented out cleans the newly expanded region and // not the aligned up expanded region. diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/memory/cardTableModRefBS.hpp --- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Fri Dec 19 12:15:34 2008 -0800 @@ -428,7 +428,7 @@ } // Mapping from address to card marking array index. - int index_for(void* p) { + size_t index_for(void* p) { assert(_whole_heap.contains(p), "out of bounds access to card marking array"); return byte_for(p) - _byte_map; diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/opto/compile.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -2192,6 +2192,9 @@ case Op_DecodeN: assert(!n->in(1)->is_EncodeP(), "should be optimized out"); + // DecodeN could be pinned on Sparc where it can't be fold into + // an address expression, see the code for Op_CastPP above. + assert(n->in(0) == NULL || !Matcher::clone_shift_expressions, "no control except on sparc"); break; case Op_EncodeP: { diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/opto/macro.cpp --- a/hotspot/src/share/vm/opto/macro.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/opto/macro.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -1724,6 +1724,13 @@ if (klass_node == NULL) { Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes()); klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) ); +#ifdef _LP64 + if (UseCompressedOops && klass_node->is_DecodeN()) { + assert(klass_node->in(1)->Opcode() == Op_LoadNKlass, "sanity"); + klass_node->in(1)->init_req(0, ctrl); + } else +#endif + klass_node->init_req(0, ctrl); } Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type()); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/prims/jni.cpp --- a/hotspot/src/share/vm/prims/jni.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/prims/jni.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -2173,7 +2173,8 @@ size_t size = os::vm_allocation_granularity(); bad_address = os::reserve_memory(size); if (bad_address != NULL) { - os::protect_memory(bad_address, size, os::MEM_PROT_READ); + os::protect_memory(bad_address, size, os::MEM_PROT_READ, + /*is_committed*/false); } } return bad_address; diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/prims/jniCheck.cpp --- a/hotspot/src/share/vm/prims/jniCheck.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/prims/jniCheck.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -112,18 +112,6 @@ static const char * fatal_non_string = "JNI string operation received a non-string"; - -// Report a JNI failure caught by -Xcheck:jni. Perform a core dump. -// Note: two variations -- one to be called when in VM state (e.g. when -// within IN_VM macro), one to be called when in NATIVE state. - -// When in VM state: -static void ReportJNIFatalError(JavaThread* thr, const char *msg) { - tty->print_cr("FATAL ERROR in native method: %s", msg); - thr->print_stack(); - os::abort(true); -} - // When in VM state: static void ReportJNIWarning(JavaThread* thr, const char *msg) { tty->print_cr("WARNING in native method: %s", msg); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/prims/jniCheck.hpp --- a/hotspot/src/share/vm/prims/jniCheck.hpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/prims/jniCheck.hpp Fri Dec 19 12:15:34 2008 -0800 @@ -22,6 +22,19 @@ * */ +extern "C" { + // Report a JNI failure caught by -Xcheck:jni. Perform a core dump. + // Note: two variations -- one to be called when in VM state (e.g. when + // within IN_VM macro), one to be called when in NATIVE state. + + // When in VM state: + static void ReportJNIFatalError(JavaThread* thr, const char *msg) { + tty->print_cr("FATAL ERROR in native method: %s", msg); + thr->print_stack(); + os::abort(true); + } +} + // // Checked JNI routines that are useful for outside of checked JNI // diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -444,9 +444,9 @@ } // Parses a memory size specification string. -static bool atomll(const char *s, jlong* result) { - jlong n = 0; - int args_read = sscanf(s, os::jlong_format_specifier(), &n); +static bool atomull(const char *s, julong* result) { + julong n = 0; + int args_read = sscanf(s, os::julong_format_specifier(), &n); if (args_read != 1) { return false; } @@ -460,15 +460,20 @@ switch (*s) { case 'T': case 't': *result = n * G * K; + // Check for overflow. + if (*result/((julong)G * K) != n) return false; return true; case 'G': case 'g': *result = n * G; + if (*result/G != n) return false; return true; case 'M': case 'm': *result = n * M; + if (*result/M != n) return false; return true; case 'K': case 'k': *result = n * K; + if (*result/K != n) return false; return true; case '\0': *result = n; @@ -478,10 +483,10 @@ } } -Arguments::ArgsRange Arguments::check_memory_size(jlong size, jlong min_size) { +Arguments::ArgsRange Arguments::check_memory_size(julong size, julong min_size) { if (size < min_size) return arg_too_small; // Check that size will fit in a size_t (only relevant on 32-bit) - if ((julong) size > max_uintx) return arg_too_big; + if (size > max_uintx) return arg_too_big; return arg_in_range; } @@ -522,10 +527,10 @@ static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) { - jlong v; + julong v; intx intx_v; bool is_neg = false; - // Check the sign first since atomll() parses only unsigned values. + // Check the sign first since atomull() parses only unsigned values. if (*value == '-') { if (!CommandLineFlags::intxAt(name, &intx_v)) { return false; @@ -533,7 +538,7 @@ value++; is_neg = true; } - if (!atomll(value, &v)) { + if (!atomull(value, &v)) { return false; } intx_v = (intx) v; @@ -1677,9 +1682,9 @@ } Arguments::ArgsRange Arguments::parse_memory_size(const char* s, - jlong* long_arg, - jlong min_size) { - if (!atomll(s, long_arg)) return arg_unreadable; + julong* long_arg, + julong min_size) { + if (!atomull(s, long_arg)) return arg_unreadable; return check_memory_size(*long_arg, min_size); } @@ -1857,7 +1862,7 @@ FLAG_SET_CMDLINE(bool, BackgroundCompilation, false); // -Xmn for compatibility with other JVM vendors } else if (match_option(option, "-Xmn", &tail)) { - jlong long_initial_eden_size = 0; + julong long_initial_eden_size = 0; ArgsRange errcode = parse_memory_size(tail, &long_initial_eden_size, 1); if (errcode != arg_in_range) { jio_fprintf(defaultStream::error_stream(), @@ -1869,7 +1874,7 @@ FLAG_SET_CMDLINE(uintx, NewSize, (size_t) long_initial_eden_size); // -Xms } else if (match_option(option, "-Xms", &tail)) { - jlong long_initial_heap_size = 0; + julong long_initial_heap_size = 0; ArgsRange errcode = parse_memory_size(tail, &long_initial_heap_size, 1); if (errcode != arg_in_range) { jio_fprintf(defaultStream::error_stream(), @@ -1882,7 +1887,7 @@ set_min_heap_size(initial_heap_size()); // -Xmx } else if (match_option(option, "-Xmx", &tail)) { - jlong long_max_heap_size = 0; + julong long_max_heap_size = 0; ArgsRange errcode = parse_memory_size(tail, &long_max_heap_size, 1); if (errcode != arg_in_range) { jio_fprintf(defaultStream::error_stream(), @@ -1915,7 +1920,7 @@ } // -Xss } else if (match_option(option, "-Xss", &tail)) { - jlong long_ThreadStackSize = 0; + julong long_ThreadStackSize = 0; ArgsRange errcode = parse_memory_size(tail, &long_ThreadStackSize, 1000); if (errcode != arg_in_range) { jio_fprintf(defaultStream::error_stream(), @@ -1931,9 +1936,9 @@ // HotSpot does not have separate native and Java stacks, ignore silently for compatibility // -Xmaxjitcodesize } else if (match_option(option, "-Xmaxjitcodesize", &tail)) { - jlong long_ReservedCodeCacheSize = 0; + julong long_ReservedCodeCacheSize = 0; ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize, - InitialCodeCacheSize); + (size_t)InitialCodeCacheSize); if (errcode != arg_in_range) { jio_fprintf(defaultStream::error_stream(), "Invalid maximum code cache size: %s\n", @@ -2238,7 +2243,7 @@ } else if (match_option(option, "-XX:TLEFragmentationRatio=", &tail)) { // No longer used. } else if (match_option(option, "-XX:TLESize=", &tail)) { - jlong long_tlab_size = 0; + julong long_tlab_size = 0; ArgsRange errcode = parse_memory_size(tail, &long_tlab_size, 1); if (errcode != arg_in_range) { jio_fprintf(defaultStream::error_stream(), @@ -2293,7 +2298,7 @@ "-XX:ParCMSPromoteBlocksToClaim in the future\n"); } else if (match_option(option, "-XX:ParallelGCOldGenAllocBufferSize=", &tail)) { - jlong old_plab_size = 0; + julong old_plab_size = 0; ArgsRange errcode = parse_memory_size(tail, &old_plab_size, 1); if (errcode != arg_in_range) { jio_fprintf(defaultStream::error_stream(), @@ -2301,13 +2306,13 @@ describe_range_error(errcode); return JNI_EINVAL; } - FLAG_SET_CMDLINE(uintx, OldPLABSize, (julong)old_plab_size); + FLAG_SET_CMDLINE(uintx, OldPLABSize, old_plab_size); jio_fprintf(defaultStream::error_stream(), "Please use -XX:OldPLABSize in place of " "-XX:ParallelGCOldGenAllocBufferSize in the future\n"); } else if (match_option(option, "-XX:ParallelGCToSpaceAllocBufferSize=", &tail)) { - jlong young_plab_size = 0; + julong young_plab_size = 0; ArgsRange errcode = parse_memory_size(tail, &young_plab_size, 1); if (errcode != arg_in_range) { jio_fprintf(defaultStream::error_stream(), @@ -2315,7 +2320,7 @@ describe_range_error(errcode); return JNI_EINVAL; } - FLAG_SET_CMDLINE(uintx, YoungPLABSize, (julong)young_plab_size); + FLAG_SET_CMDLINE(uintx, YoungPLABSize, young_plab_size); jio_fprintf(defaultStream::error_stream(), "Please use -XX:YoungPLABSize in place of " "-XX:ParallelGCToSpaceAllocBufferSize in the future\n"); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/runtime/arguments.hpp --- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/runtime/arguments.hpp Fri Dec 19 12:15:34 2008 -0800 @@ -339,9 +339,9 @@ } static bool verify_percentage(uintx value, const char* name); static void describe_range_error(ArgsRange errcode); - static ArgsRange check_memory_size(jlong size, jlong min_size); - static ArgsRange parse_memory_size(const char* s, jlong* long_arg, - jlong min_size); + static ArgsRange check_memory_size(julong size, julong min_size); + static ArgsRange parse_memory_size(const char* s, julong* long_arg, + julong min_size); // methods to build strings from individual args static void build_jvm_args(const char* arg); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Dec 19 12:15:34 2008 -0800 @@ -821,7 +821,7 @@ product(bool, ClassUnloading, true, \ "Do unloading of classes") \ \ - diagnostic(bool, LinkWellKnownClasses, true, \ + diagnostic(bool, LinkWellKnownClasses, false, \ "Resolve a well known class as soon as its name is seen") \ \ develop(bool, DisableStartThread, false, \ diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/runtime/javaCalls.cpp --- a/hotspot/src/share/vm/runtime/javaCalls.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/runtime/javaCalls.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -309,8 +309,12 @@ CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();) - // Make sure that the arguments have the right type - debug_only(args->verify(method, result->get_type(), thread)); + // Verify the arguments + + if (CheckJNICalls) { + args->verify(method, result->get_type(), thread); + } + else debug_only(args->verify(method, result->get_type(), thread)); // Ignore call if method is empty if (method->is_empty_method()) { @@ -431,24 +435,26 @@ return TaggedStackInterpreter ? _parameters : _value; } -//-------------------------------------------------------------------------------------- -// Non-Product code -#ifndef PRODUCT class SignatureChekker : public SignatureIterator { private: bool *_is_oop; int _pos; BasicType _return_type; + intptr_t* _value; + Thread* _thread; public: bool _is_return; - SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop) : SignatureIterator(signature) { + SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { _is_oop = is_oop; _is_return = false; _return_type = return_type; _pos = 0; + _value = value; + _thread = thread; + if (!is_static) { check_value(true); // Receiver must be an oop } @@ -489,6 +495,24 @@ check_return_type(t); return; } + + // verify handle and the oop pointed to by handle + int p = _pos; + bool bad = false; + // If argument is oop + if (_is_oop[p]) { + intptr_t v = _value[p]; + if (v != 0 ) { + size_t t = (size_t)v; + bad = (t < (size_t)os::vm_page_size() ) || !(*(oop*)v)->is_oop_or_null(true); + if (CheckJNICalls && bad) { + ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument"); + } + } + // for the regular debug case. + assert(!bad, "Bad JNI oop argument"); + } + check_value(true); } @@ -505,6 +529,7 @@ void do_array(int begin, int end) { check_obj(T_OBJECT); } }; + void JavaCallArguments::verify(methodHandle method, BasicType return_type, Thread *thread) { guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); @@ -515,10 +540,9 @@ // Check that oop information is correct symbolHandle signature (thread, method->signature()); - SignatureChekker sc(signature, return_type, method->is_static(),_is_oop); + SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); sc.iterate_parameters(); sc.check_doing_return(true); sc.iterate_returntype(); } -#endif // PRODUCT diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/runtime/javaCalls.hpp --- a/hotspot/src/share/vm/runtime/javaCalls.hpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/runtime/javaCalls.hpp Fri Dec 19 12:15:34 2008 -0800 @@ -150,7 +150,7 @@ int size_of_parameters() const { return _size; } // Verify that pushed arguments fits a given method - void verify(methodHandle method, BasicType return_type, Thread *thread) PRODUCT_RETURN; + void verify(methodHandle method, BasicType return_type, Thread *thread); }; // All calls to Java have to go via JavaCalls. Sets up the stack frame diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/runtime/os.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -932,8 +932,9 @@ // the mutator thread if such case is encountered. See bug 6546278 for details. Thread::muxAcquire(&SerializePageLock, "serialize_thread_states"); os::protect_memory((char *)os::get_memory_serialize_page(), - os::vm_page_size(), MEM_PROT_READ, /*is_committed*/true ); - os::unguard_memory((char *)os::get_memory_serialize_page(), os::vm_page_size()); + os::vm_page_size(), MEM_PROT_READ); + os::protect_memory((char *)os::get_memory_serialize_page(), + os::vm_page_size(), MEM_PROT_RW); Thread::muxRelease(&SerializePageLock); } diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/runtime/os.hpp --- a/hotspot/src/share/vm/runtime/os.hpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/runtime/os.hpp Fri Dec 19 12:15:34 2008 -0800 @@ -208,7 +208,7 @@ enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX }; static bool protect_memory(char* addr, size_t bytes, ProtType prot, - bool is_committed = false); + bool is_committed = true); static bool guard_memory(char* addr, size_t bytes); static bool unguard_memory(char* addr, size_t bytes); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/runtime/sharedRuntime.cpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -556,7 +556,10 @@ // the caller was at a call site, it's safe to destroy all // caller-saved registers, as these entry points do. VtableStub* vt_stub = VtableStubs::stub_containing(pc); - guarantee(vt_stub != NULL, "unable to find SEGVing vtable stub"); + + // If vt_stub is NULL, then return NULL to signal handler to report the SEGV error. + if (vt_stub == NULL) return NULL; + if (vt_stub->is_abstract_method_error(pc)) { assert(!vt_stub->is_vtable_stub(), "should never see AbstractMethodErrors from vtable-type VtableStubs"); return StubRoutines::throw_AbstractMethodError_entry(); @@ -565,7 +568,9 @@ } } else { CodeBlob* cb = CodeCache::find_blob(pc); - guarantee(cb != NULL, "exception happened outside interpreter, nmethods and vtable stubs (1)"); + + // If code blob is NULL, then return NULL to signal handler to report the SEGV error. + if (cb == NULL) return NULL; // Exception happened in CodeCache. Must be either: // 1. Inline-cache check in C2I handler blob, @@ -574,7 +579,7 @@ if (!cb->is_nmethod()) { guarantee(cb->is_adapter_blob(), - "exception happened outside interpreter, nmethods and vtable stubs (2)"); + "exception happened outside interpreter, nmethods and vtable stubs (1)"); // There is no handler here, so we will simply unwind. return StubRoutines::throw_NullPointerException_at_call_entry(); } diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/runtime/synchronizer.cpp --- a/hotspot/src/share/vm/runtime/synchronizer.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -3363,13 +3363,13 @@ // If the wakee is cold then transiently setting it's affinity // to the current CPU is a good idea. // See http://j2se.east/~dice/PERSIST/050624-PullAffinity.txt + DTRACE_MONITOR_PROBE(contended__exit, this, object(), Self); Trigger->unpark() ; // Maintain stats and report events to JVMTI if (ObjectSynchronizer::_sync_Parks != NULL) { ObjectSynchronizer::_sync_Parks->inc() ; } - DTRACE_MONITOR_PROBE(contended__exit, this, object(), Self); } diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/services/management.cpp --- a/hotspot/src/share/vm/services/management.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/services/management.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -694,10 +694,10 @@ -1); } - if (threshold > max_intx) { - THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), - "Invalid threshold value > max value of size_t", - -1); + if ((size_t)threshold > max_uintx) { + stringStream st; + st.print("Invalid valid threshold value. Threshold value (" UINT64_FORMAT ") > max value of size_t (" SIZE_FORMAT ")", (size_t)threshold, max_uintx); + THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), st.as_string(), -1); } MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_(0L)); diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/src/share/vm/utilities/vmError.cpp --- a/hotspot/src/share/vm/utilities/vmError.cpp Thu Dec 18 10:54:01 2008 -0800 +++ b/hotspot/src/share/vm/utilities/vmError.cpp Fri Dec 19 12:15:34 2008 -0800 @@ -332,6 +332,8 @@ // VM version st->print_cr("#"); + JDK_Version::current().to_string(buf, sizeof(buf)); + st->print_cr("# JRE version: %s", buf); st->print_cr("# Java VM: %s (%s %s %s %s)", Abstract_VM_Version::vm_name(), Abstract_VM_Version::vm_release(), diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/test/compiler/6757316/Test6757316.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/6757316/Test6757316.java Fri Dec 19 12:15:34 2008 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright 2008 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 6757316 + * @summary load_constant() produces a wrong long constant, with high a low words swapped + * @run main/othervm -Xcomp Test6757316 + */ + +public class Test6757316 { + public static void main(String[] args) { + long[] arr = { + 0x11111111aaaaaaaaL, + 0xaaaaaaaa11111111L, + 0x11111111aaaaaaaaL, + 0xaaaaaaaa11111111L + }; + if (arr[0] == arr[1]) { + throw new InternalError(); + } + } +} diff -r 56dd12dd6cb3 -r 4632ed70b874 hotspot/test/compiler/6758234/Test6758234.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/6758234/Test6758234.java Fri Dec 19 12:15:34 2008 -0800 @@ -0,0 +1,40 @@ +/* + * Copyright 2008 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 6758234 + * @summary if (k cond (a ? : b: c)) returns reversed answer if k is constant and b and c are longs + * @run main/othervm -Xcomp -XX:CompileOnly=Test6758234.main Test6758234 + */ + +public class Test6758234 { + static int x = 0; + static int y = 1; + + public static void main(String[] args) { + if (1 != ((x < y) ? 1L : 0)) { + throw new InternalError(); + } + } +}