This commit is contained in:
Tim Bell 2009-01-09 21:54:17 -08:00
commit b1b8994004
134 changed files with 3437 additions and 968 deletions

View File

@ -16,3 +16,4 @@ a2879b2837f5a4c87e9542efe69ef138194af8ff jdk7-b38
126f365cec6c3c2c72de934fa1c64b5f082b55b5 jdk7-b39
3c53424bbe3bb77e01b468b4b0140deec33e11fc jdk7-b40
3cb2a607c347934f8e7e86f840a094c28b08d9ea jdk7-b41
caf58ffa084568990cbb3441f9ae188e36b31770 jdk7-b42

View File

@ -16,3 +16,4 @@ cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38
ab523b49de1fc73fefe6855ce1e0349bdbd7af29 jdk7-b39
44be42de6693063fb191989bf0e188de2fa51e7c jdk7-b40
541bdc5ad32fc33255944d0a044ad992f3d915e8 jdk7-b41
94052b87287303527125026fe4b2698cf867ea83 jdk7-b42

View File

@ -16,3 +16,4 @@ ef6af34d75a7b44e77083f1d4ee47631fa09d3b4 jdk7-b31
55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39
184e21992f47a8d730df1adc5b21a108f3125489 jdk7-b40
c90eeda9594ed2983403e2049aed8d503126c62e jdk7-b41
ccd6a16502e0650d91d85c4b86be05cbcd461a87 jdk7-b42

View File

@ -16,3 +16,4 @@ d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
81a0cbe3b28460ce836109934ece03db7afaf9cc jdk7-b40
f9d938ede1960d18cb7cf23c645b026519c1a678 jdk7-b41
ad8c8ca4ab0f4c86e74c061958f44a8f4a930f2c jdk7-b42

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2008
HS_MAJOR_VER=14
HS_MINOR_VER=0
HS_BUILD_NUMBER=09
HS_BUILD_NUMBER=10
JDK_MAJOR_VER=1
JDK_MINOR_VER=7

View File

@ -7,5 +7,13 @@
#
# adlc-updater <file> <source-dir> <target-dir>
#
[ -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 )

View File

@ -54,10 +54,12 @@ VPATH += $(Src_Dirs_V:%=%:)
Src_Dirs_I = ${Src_Dirs} $(GENERATED)
INCLUDES += $(Src_Dirs_I:%=-I%)
# Force assertions on.
SYSDEFS += -DASSERT
# set flags for adlc compilation
CPPFLAGS = $(SYSDEFS) $(INCLUDES)
# Force assertions on.
CPPFLAGS += -DASSERT
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
# Suppress warnings (for now)
CFLAGS_WARN = -w
@ -125,7 +127,15 @@ $(GENERATEDFILES): refresh_adfiles
# 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_<arch>*.cpp files.
# But -g will put #line directives in those files pointing back to <arch>.ad.
#ADLCFLAGS += -g
ifdef LP64
ADLCFLAGS += -D_LP64
@ -140,6 +150,8 @@ endif
#
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 @@ ADLC_UPDATER = adlc_updater
# 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 @@ refresh_adfiles: $(EXEC) $(SOURCE.AD)
# #########################################################################
$(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 $<

View File

@ -7,5 +7,13 @@
#
# adlc-updater <file> <source-dir> <target-dir>
#
[ -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 )

View File

@ -54,10 +54,12 @@ VPATH += $(Src_Dirs_V:%=%:)
Src_Dirs_I = ${Src_Dirs} $(GENERATED)
INCLUDES += $(Src_Dirs_I:%=-I%)
# Force assertions on.
SYSDEFS += -DASSERT
# set flags for adlc compilation
CPPFLAGS = $(SYSDEFS) $(INCLUDES)
# Force assertions on.
CPPFLAGS += -DASSERT
ifndef USE_GCC
# We need libCstd.so for adlc
CFLAGS += -library=Cstd -g
@ -141,7 +143,15 @@ $(GENERATEDFILES): refresh_adfiles
# 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_<arch>*.cpp files.
# But -g will put #line directives in those files pointing back to <arch>.ad.
#ADLCFLAGS += -g
ifdef LP64
ADLCFLAGS += -D_LP64
@ -156,6 +166,8 @@ endif
#
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 @@ ADLC_UPDATER = adlc_updater
# 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 @@ refresh_adfiles: $(EXEC) $(SOURCE.AD)
# #########################################################################
$(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 $<

View File

@ -2500,7 +2500,7 @@ bool os::guard_memory(char* addr, size_t size) {
}
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

View File

@ -1638,16 +1638,24 @@ inline hrtime_t oldgetTimeNanos() {
// getTimeNanos is guaranteed to not move backward on Solaris
inline hrtime_t getTimeNanos() {
if (VM_Version::supports_cx8()) {
bool retry = false;
hrtime_t newtime = gethrtime();
hrtime_t oldmaxtime = max_hrtime;
hrtime_t retmaxtime = oldmaxtime;
while ((newtime > retmaxtime) && (retry == false || retmaxtime != oldmaxtime)) {
oldmaxtime = retmaxtime;
retmaxtime = Atomic::cmpxchg(newtime, (volatile jlong *)&max_hrtime, oldmaxtime);
retry = true;
}
return (newtime > retmaxtime) ? newtime : retmaxtime;
const hrtime_t now = gethrtime();
const hrtime_t prev = max_hrtime;
if (now <= prev) return prev; // same or retrograde time;
const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev);
assert(obsv >= prev, "invariant"); // Monotonicity
// If the CAS succeeded then we're done and return "now".
// If the CAS failed and the observed value "obs" is >= now then
// we should return "obs". If the CAS failed and now > obs > prv then
// some other thread raced this thread and installed a new value, in which case
// we could either (a) retry the entire operation, (b) retry trying to install now
// or (c) just return obs. We use (c). No loop is required although in some cases
// we might discard a higher "now" value in deference to a slightly lower but freshly
// installed obs value. That's entirely benign -- it admits no new orderings compared
// to (a) or (b) -- and greatly reduces coherence traffic.
// We might also condition (c) on the magnitude of the delta between obs and now.
// Avoiding excessive CAS operations to hot RW locations is critical.
// See http://blogs.sun.com/dave/entry/cas_and_cache_trivia_invalidate
return (prev == obsv) ? now : obsv ;
} else {
return oldgetTimeNanos();
}
@ -3026,6 +3034,8 @@ static bool solaris_mprotect(char* addr, size_t bytes, int prot) {
// Protect memory (Used to pass readonly pages through
// JNI GetArray<type>Elements 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 +3059,7 @@ bool os::guard_memory(char* addr, size_t bytes) {
}
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

View File

@ -2020,10 +2020,11 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
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];
@ -2755,12 +2756,12 @@ bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
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) { }

View File

@ -422,10 +422,11 @@ JVM_handle_linux_signal(int sig,
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];

View File

@ -203,10 +203,10 @@ frame os::get_sender_for_C_frame(frame* fr) {
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 @@ int JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, int abort_
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];

View File

@ -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)

View File

@ -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)

View File

@ -108,6 +108,7 @@ void ADLParser::parse() {
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 {
@ -787,8 +788,10 @@ void ADLParser::reg_parse(void) {
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(); }
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 @@ void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) {
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 @@ void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) {
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 @@ void ADLParser::reg_class_parse(void) {
return;
}
RegDef *regDef = _AD._register->getRegDef(rname);
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 @@ Predicate *ADLParser::pred_parse(void) {
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 @@ FormatRule* ADLParser::format_parse(void) {
// 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,7 +3955,6 @@ char* ADLParser::find_cpp_block(const char* description) {
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();
next = _ptr + 1;
while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
@ -3958,16 +3970,17 @@ char* ADLParser::find_cpp_block(const char* description) {
_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);
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 @@ char* ADLParser::get_expr(const char *desc, const char *stop_chars) {
// 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 @@ char *ADLParser::get_ident_common(bool do_preproc) {
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 @@ void ADLParser::get_effectlist(FormDict &effects, FormDict &operands) {
}
//-------------------------------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 @@ void ADLParser::parse_err(int flag, const char *fmt, ...) {
// 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 @@ char ADLParser::cur_char() {
//---------------------------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 @@ void ADLParser::next_char_or_line() {
//---------------------------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 @@ bool ADLParser::is_int_token(const char* token, int& intval) {
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++;

View File

@ -93,6 +93,7 @@ protected:
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 @@ protected:
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 @@ protected:
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 @@ public:
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
};

View File

@ -140,7 +140,7 @@ bool MatchList::search(const char *opc, const char *res, const char *lch,
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;
}
}

View File

@ -458,7 +458,7 @@ void ArchDesc::buildDFA(FILE* fp) {
class dfa_shared_preds {
enum { count = 2 };
enum { count = 4 };
static bool _found[count];
static const char* _type [count];
@ -479,12 +479,15 @@ class dfa_shared_preds {
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 @@ public:
}
};
// 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) {

View File

@ -68,6 +68,7 @@ class FileBuff {
// 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()).

View File

@ -1102,10 +1102,7 @@ bool equivalent_predicates( const InstructForm *instr1, const InstructForm *inst
}
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;
}
}

View File

@ -1210,8 +1210,8 @@ LIR_Opr LIRGenerator::load_constant(LIR_Const* c) {
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;

View File

@ -327,8 +327,6 @@ class BlockMerger: public BlockClosure {
BlockBegin* fsux = if_->fsux();
if (swapped) {
cond = Instruction::mirror(cond);
tsux = if_->fsux();
fsux = if_->tsux();
}
BlockBegin* tblock = tval->compare(cond, con, tsux, fsux);

View File

@ -842,6 +842,13 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
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);

View File

@ -581,6 +581,7 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
interf = KlassHandle(THREAD, k);
vmtimer->resume();
if (LinkWellKnownClasses) // my super type is well known to me
cp->klass_at_put(interface_index, interf()); // eagerly resolve
}
@ -2699,6 +2700,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
CHECK_(nullHandle));
KlassHandle kh (THREAD, k);
super_klass = instanceKlassHandle(THREAD, kh());
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()) {
@ -3128,6 +3130,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
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));
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());

View File

@ -2954,7 +2954,7 @@ public:
// The object has been either evacuated or is dead. Fill it with a
// dummy object.
MemRegion mr((HeapWord*)obj, obj->size());
SharedHeap::fill_region_with_object(mr);
CollectedHeap::fill_with_object(mr);
_cm->clearRangeBothMaps(mr);
}
}
@ -3225,7 +3225,7 @@ void G1CollectedHeap::par_allocate_remaining_space(HeapRegion* r) {
// Otherwise, try to claim it.
block = r->par_allocate(free_words);
} while (block == NULL);
SharedHeap::fill_region_with_object(MemRegion(block, free_words));
fill_with_object(block, free_words);
}
#define use_local_bitmaps 1
@ -3619,9 +3619,8 @@ public:
guarantee(alloc_buffer(purpose)->contains(obj + word_sz - 1),
"should contain whole object");
alloc_buffer(purpose)->undo_allocation(obj, word_sz);
}
else {
SharedHeap::fill_region_with_object(MemRegion(obj, word_sz));
} else {
CollectedHeap::fill_with_object(obj, word_sz);
add_to_undo_waste(word_sz);
}
}

View File

@ -181,7 +181,7 @@ public:
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();

View File

@ -102,7 +102,7 @@ HeapRegionSeq::alloc_obj_from_region_index(int ind, size_t word_size) {
HeapWord* tmp = hr->allocate(sz);
assert(tmp != NULL, "Humongous allocation failure");
MemRegion mr = MemRegion(tmp, sz);
SharedHeap::fill_region_with_object(mr);
CollectedHeap::fill_with_object(mr);
hr->declare_filled_region_to_BOT(mr);
if (i == first) {
first_hr->set_startsHumongous();

View File

@ -51,14 +51,14 @@ void ParGCAllocBuffer::retire(bool end_of_gc, bool retain) {
if (_retained) {
// If the buffer had been retained shorten the previous filler object.
assert(_retained_filler.end() <= _top, "INVARIANT");
SharedHeap::fill_region_with_object(_retained_filler);
CollectedHeap::fill_with_object(_retained_filler);
// Wasted space book-keeping, otherwise (normally) done in invalidate()
_wasted += _retained_filler.word_size();
_retained = false;
}
assert(!end_of_gc || !_retained, "At this point, end_of_gc ==> !_retained.");
if (_top < _hard_end) {
SharedHeap::fill_region_with_object(MemRegion(_top, _hard_end));
CollectedHeap::fill_with_object(_top, _hard_end);
if (!retain) {
invalidate();
} else {
@ -155,7 +155,7 @@ ParGCAllocBufferWithBOT::ParGCAllocBufferWithBOT(size_t word_sz,
// modifying the _next_threshold state in the BOT.
void ParGCAllocBufferWithBOT::fill_region_with_block(MemRegion mr,
bool contig) {
SharedHeap::fill_region_with_object(mr);
CollectedHeap::fill_with_object(mr);
if (contig) {
_bt.alloc_block(mr.start(), mr.end());
} else {
@ -171,7 +171,7 @@ HeapWord* ParGCAllocBufferWithBOT::allocate_slow(size_t word_sz) {
"or else _true_end should be equal to _hard_end");
assert(_retained, "or else _true_end should be equal to _hard_end");
assert(_retained_filler.end() <= _top, "INVARIANT");
SharedHeap::fill_region_with_object(_retained_filler);
CollectedHeap::fill_with_object(_retained_filler);
if (_top < _hard_end) {
fill_region_with_block(MemRegion(_top, _hard_end), true);
}
@ -316,11 +316,9 @@ void ParGCAllocBufferWithBOT::retire(bool end_of_gc, bool retain) {
while (_top <= chunk_boundary) {
assert(pointer_delta(_hard_end, chunk_boundary) >= AlignmentReserve,
"Consequence of last card handling above.");
MemRegion chunk_portion(chunk_boundary, _hard_end);
_bt.BlockOffsetArray::alloc_block(chunk_portion.start(),
chunk_portion.end());
SharedHeap::fill_region_with_object(chunk_portion);
_hard_end = chunk_portion.start();
_bt.BlockOffsetArray::alloc_block(chunk_boundary, _hard_end);
CollectedHeap::fill_with_object(chunk_boundary, _hard_end);
_hard_end = chunk_boundary;
chunk_boundary -= ChunkSizeInWords;
}
_end = _hard_end - AlignmentReserve;

View File

@ -201,7 +201,7 @@ void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj,
"Should contain whole object.");
to_space_alloc_buffer()->undo_allocation(obj, word_sz);
} else {
SharedHeap::fill_region_with_object(MemRegion(obj, word_sz));
CollectedHeap::fill_with_object(obj, word_sz);
}
}

View File

@ -389,7 +389,7 @@ bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
// full GC.
const size_t alignment = old_gen->virtual_space()->alignment();
const size_t eden_used = eden_space->used_in_bytes();
const size_t promoted = (size_t)(size_policy->avg_promoted()->padded_average());
const size_t promoted = (size_t)size_policy->avg_promoted()->padded_average();
const size_t absorb_size = align_size_up(eden_used + promoted, alignment);
const size_t eden_capacity = eden_space->capacity_in_bytes();
@ -416,16 +416,14 @@ bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
// Fill the unused part of the old gen.
MutableSpace* const old_space = old_gen->object_space();
MemRegion old_gen_unused(old_space->top(), old_space->end());
HeapWord* const unused_start = old_space->top();
size_t const unused_words = pointer_delta(old_space->end(), unused_start);
// If the unused part of the old gen cannot be filled, skip
// absorbing eden.
if (old_gen_unused.word_size() < SharedHeap::min_fill_size()) {
return false;
if (unused_words > 0) {
if (unused_words < CollectedHeap::min_fill_size()) {
return false; // If the old gen cannot be filled, must give up.
}
if (!old_gen_unused.is_empty()) {
SharedHeap::fill_region_with_object(old_gen_unused);
CollectedHeap::fill_with_objects(unused_start, unused_words);
}
// Take the live data from eden and set both top and end in the old gen to
@ -441,9 +439,8 @@ bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
// Update the object start array for the filler object and the data from eden.
ObjectStartArray* const start_array = old_gen->start_array();
HeapWord* const start = old_gen_unused.start();
for (HeapWord* addr = start; addr < new_top; addr += oop(addr)->size()) {
start_array->allocate_block(addr);
for (HeapWord* p = unused_start; p < new_top; p += oop(p)->size()) {
start_array->allocate_block(p);
}
// Could update the promoted average here, but it is not typically updated at

View File

@ -275,22 +275,9 @@ bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
HeapWord* q, size_t deadlength) {
if (allowed_deadspace_words >= deadlength) {
allowed_deadspace_words -= deadlength;
oop(q)->set_mark(markOopDesc::prototype()->set_marked());
const size_t aligned_min_int_array_size =
align_object_size(typeArrayOopDesc::header_size(T_INT));
if (deadlength >= aligned_min_int_array_size) {
oop(q)->set_klass(Universe::intArrayKlassObj());
assert(((deadlength - aligned_min_int_array_size) * (HeapWordSize/sizeof(jint))) < (size_t)max_jint,
"deadspace too big for Arrayoop");
typeArrayOop(q)->set_length((int)((deadlength - aligned_min_int_array_size)
* (HeapWordSize/sizeof(jint))));
} else {
assert((int) deadlength == instanceOopDesc::header_size(),
"size for smallest fake dead object doesn't match");
oop(q)->set_klass(SystemDictionary::object_klass());
}
assert((int) deadlength == oop(q)->size(),
"make sure size for fake dead object match");
CollectedHeap::fill_with_object(q, deadlength);
oop(q)->set_mark(oop(q)->mark()->set_marked());
assert((int) deadlength == oop(q)->size(), "bad filler object size");
// Recall that we required "q == compaction_top".
return true;
} else {

View File

@ -36,6 +36,123 @@ class PreGCValues;
class MoveAndUpdateClosure;
class RefProcTaskExecutor;
// The SplitInfo class holds the information needed to 'split' a source region
// so that the live data can be copied to two destination *spaces*. Normally,
// all the live data in a region is copied to a single destination space (e.g.,
// everything live in a region in eden is copied entirely into the old gen).
// However, when the heap is nearly full, all the live data in eden may not fit
// into the old gen. Copying only some of the regions from eden to old gen
// requires finding a region that does not contain a partial object (i.e., no
// live object crosses the region boundary) somewhere near the last object that
// does fit into the old gen. Since it's not always possible to find such a
// region, splitting is necessary for predictable behavior.
//
// A region is always split at the end of the partial object. This avoids
// additional tests when calculating the new location of a pointer, which is a
// very hot code path. The partial object and everything to its left will be
// copied to another space (call it dest_space_1). The live data to the right
// of the partial object will be copied either within the space itself, or to a
// different destination space (distinct from dest_space_1).
//
// Split points are identified during the summary phase, when region
// destinations are computed: data about the split, including the
// partial_object_size, is recorded in a SplitInfo record and the
// partial_object_size field in the summary data is set to zero. The zeroing is
// possible (and necessary) since the partial object will move to a different
// destination space than anything to its right, thus the partial object should
// not affect the locations of any objects to its right.
//
// The recorded data is used during the compaction phase, but only rarely: when
// the partial object on the split region will be copied across a destination
// region boundary. This test is made once each time a region is filled, and is
// a simple address comparison, so the overhead is negligible (see
// PSParallelCompact::first_src_addr()).
//
// Notes:
//
// Only regions with partial objects are split; a region without a partial
// object does not need any extra bookkeeping.
//
// At most one region is split per space, so the amount of data required is
// constant.
//
// A region is split only when the destination space would overflow. Once that
// happens, the destination space is abandoned and no other data (even from
// other source spaces) is targeted to that destination space. Abandoning the
// destination space may leave a somewhat large unused area at the end, if a
// large object caused the overflow.
//
// Future work:
//
// More bookkeeping would be required to continue to use the destination space.
// The most general solution would allow data from regions in two different
// source spaces to be "joined" in a single destination region. At the very
// least, additional code would be required in next_src_region() to detect the
// join and skip to an out-of-order source region. If the join region was also
// the last destination region to which a split region was copied (the most
// likely case), then additional work would be needed to get fill_region() to
// stop iteration and switch to a new source region at the right point. Basic
// idea would be to use a fake value for the top of the source space. It is
// doable, if a bit tricky.
//
// A simpler (but less general) solution would fill the remainder of the
// destination region with a dummy object and continue filling the next
// destination region.
class SplitInfo
{
public:
// Return true if this split info is valid (i.e., if a split has been
// recorded). The very first region cannot have a partial object and thus is
// never split, so 0 is the 'invalid' value.
bool is_valid() const { return _src_region_idx > 0; }
// Return true if this split holds data for the specified source region.
inline bool is_split(size_t source_region) const;
// The index of the split region, the size of the partial object on that
// region and the destination of the partial object.
size_t src_region_idx() const { return _src_region_idx; }
size_t partial_obj_size() const { return _partial_obj_size; }
HeapWord* destination() const { return _destination; }
// The destination count of the partial object referenced by this split
// (either 1 or 2). This must be added to the destination count of the
// remainder of the source region.
unsigned int destination_count() const { return _destination_count; }
// If a word within the partial object will be written to the first word of a
// destination region, this is the address of the destination region;
// otherwise this is NULL.
HeapWord* dest_region_addr() const { return _dest_region_addr; }
// If a word within the partial object will be written to the first word of a
// destination region, this is the address of that word within the partial
// object; otherwise this is NULL.
HeapWord* first_src_addr() const { return _first_src_addr; }
// Record the data necessary to split the region src_region_idx.
void record(size_t src_region_idx, size_t partial_obj_size,
HeapWord* destination);
void clear();
DEBUG_ONLY(void verify_clear();)
private:
size_t _src_region_idx;
size_t _partial_obj_size;
HeapWord* _destination;
unsigned int _destination_count;
HeapWord* _dest_region_addr;
HeapWord* _first_src_addr;
};
inline bool SplitInfo::is_split(size_t region_idx) const
{
return _src_region_idx == region_idx && is_valid();
}
class SpaceInfo
{
public:
@ -58,18 +175,23 @@ class SpaceInfo
// is no start array.
ObjectStartArray* start_array() const { return _start_array; }
SplitInfo& split_info() { return _split_info; }
void set_space(MutableSpace* s) { _space = s; }
void set_new_top(HeapWord* addr) { _new_top = addr; }
void set_min_dense_prefix(HeapWord* addr) { _min_dense_prefix = addr; }
void set_dense_prefix(HeapWord* addr) { _dense_prefix = addr; }
void set_start_array(ObjectStartArray* s) { _start_array = s; }
void publish_new_top() const { _space->set_top(_new_top); }
private:
MutableSpace* _space;
HeapWord* _new_top;
HeapWord* _min_dense_prefix;
HeapWord* _dense_prefix;
ObjectStartArray* _start_array;
SplitInfo _split_info;
};
class ParallelCompactData
@ -230,9 +352,14 @@ public:
// must be region-aligned; end need not be.
void summarize_dense_prefix(HeapWord* beg, HeapWord* end);
bool summarize(HeapWord* target_beg, HeapWord* target_end,
HeapWord* summarize_split_space(size_t src_region, SplitInfo& split_info,
HeapWord* destination, HeapWord* target_end,
HeapWord** target_next);
bool summarize(SplitInfo& split_info,
HeapWord* source_beg, HeapWord* source_end,
HeapWord** target_next, HeapWord** source_next = 0);
HeapWord** source_next,
HeapWord* target_beg, HeapWord* target_end,
HeapWord** target_next);
void clear();
void clear_range(size_t beg_region, size_t end_region);
@ -838,13 +965,31 @@ class PSParallelCompact : AllStatic {
// non-empty.
static void fill_dense_prefix_end(SpaceId id);
// Clear the summary data source_region field for the specified addresses.
static void clear_source_region(HeapWord* beg_addr, HeapWord* end_addr);
#ifndef PRODUCT
// Routines to provoke splitting a young gen space (ParallelOldGCSplitALot).
// Fill the region [start, start + words) with live object(s). Only usable
// for the old and permanent generations.
static void fill_with_live_objects(SpaceId id, HeapWord* const start,
size_t words);
// Include the new objects in the summary data.
static void summarize_new_objects(SpaceId id, HeapWord* start);
// Add live objects to a survivor space since it's rare that both survivors
// are non-empty.
static void provoke_split_fill_survivor(SpaceId id);
// Add live objects and/or choose the dense prefix to provoke splitting.
static void provoke_split(bool & maximum_compaction);
#endif
static void summarize_spaces_quick();
static void summarize_space(SpaceId id, bool maximum_compaction);
static void summary_phase(ParCompactionManager* cm, bool maximum_compaction);
// The space that is compacted after space_id.
static SpaceId next_compaction_space_id(SpaceId space_id);
// Adjust addresses in roots. Does not adjust addresses in heap.
static void adjust_roots();
@ -999,6 +1144,7 @@ class PSParallelCompact : AllStatic {
// Return the address of the word to be copied to dest_addr, which must be
// aligned to a region boundary.
static HeapWord* first_src_addr(HeapWord* const dest_addr,
SpaceId src_space_id,
size_t src_region_idx);
// Determine the next source region, set closure.source() to the start of the
@ -1012,8 +1158,10 @@ class PSParallelCompact : AllStatic {
HeapWord* end_addr);
// Decrement the destination count for each non-empty source region in the
// range [beg_region, region(region_align_up(end_addr))).
// range [beg_region, region(region_align_up(end_addr))). If the destination
// count for a region goes to 0 and it needs to be filled, enqueue it.
static void decrement_destination_counts(ParCompactionManager* cm,
SpaceId src_space_id,
size_t beg_region,
HeapWord* end_addr);
@ -1081,9 +1229,15 @@ class PSParallelCompact : AllStatic {
const SpaceId id,
const bool maximum_compaction,
HeapWord* const addr);
static void summary_phase_msg(SpaceId dst_space_id,
HeapWord* dst_beg, HeapWord* dst_end,
SpaceId src_space_id,
HeapWord* src_beg, HeapWord* src_end);
#endif // #ifndef PRODUCT
#ifdef ASSERT
// Sanity check the new location of a word in the heap.
static inline void check_new_location(HeapWord* old_addr, HeapWord* new_addr);
// Verify that all the regions have been emptied.
static void verify_complete(SpaceId space_id);
#endif // #ifdef ASSERT
@ -1251,6 +1405,15 @@ inline void PSParallelCompact::adjust_pointer(T* p,
}
}
#ifdef ASSERT
inline void
PSParallelCompact::check_new_location(HeapWord* old_addr, HeapWord* new_addr)
{
assert(old_addr >= new_addr || space_id(old_addr) != space_id(new_addr),
"must move left or to a different space");
}
#endif // ASSERT
class MoveAndUpdateClosure: public ParMarkBitMapClosure {
public:
inline MoveAndUpdateClosure(ParMarkBitMap* bitmap, ParCompactionManager* cm,
@ -1324,31 +1487,28 @@ inline void UpdateOnlyClosure::do_addr(HeapWord* addr)
oop(addr)->update_contents(compaction_manager());
}
class FillClosure: public ParMarkBitMapClosure {
class FillClosure: public ParMarkBitMapClosure
{
public:
FillClosure(ParCompactionManager* cm, PSParallelCompact::SpaceId space_id) :
ParMarkBitMapClosure(PSParallelCompact::mark_bitmap(), cm),
_space_id(space_id),
_start_array(PSParallelCompact::start_array(space_id)) {
assert(_space_id == PSParallelCompact::perm_space_id ||
_space_id == PSParallelCompact::old_space_id,
_start_array(PSParallelCompact::start_array(space_id))
{
assert(space_id == PSParallelCompact::perm_space_id ||
space_id == PSParallelCompact::old_space_id,
"cannot use FillClosure in the young gen");
assert(bitmap() != NULL, "need a bitmap");
assert(_start_array != NULL, "need a start array");
}
void fill_region(HeapWord* addr, size_t size) {
MemRegion region(addr, size);
SharedHeap::fill_region_with_object(region);
_start_array->allocate_block(addr);
}
virtual IterationStatus do_addr(HeapWord* addr, size_t size) {
fill_region(addr, size);
CollectedHeap::fill_with_objects(addr, size);
HeapWord* const end = addr + size;
do {
_start_array->allocate_block(addr);
addr += oop(addr)->size();
} while (addr < end);
return ParMarkBitMap::incomplete;
}
private:
const PSParallelCompact::SpaceId _space_id;
ObjectStartArray* const _start_array;
};

View File

@ -499,26 +499,15 @@ oop PSPromotionManager::copy_to_survivor_space(oop o, bool depth_first) {
// We lost, someone else "owns" this object
guarantee(o->is_forwarded(), "Object must be forwarded if the cas failed.");
// Unallocate the space used. NOTE! We may have directly allocated
// the object. If so, we cannot deallocate it, so we have to test!
// Try to deallocate the space. If it was directly allocated we cannot
// deallocate it, so we have to test. If the deallocation fails,
// overwrite with a filler object.
if (new_obj_is_tenured) {
if (!_old_lab.unallocate_object(new_obj)) {
// The promotion lab failed to unallocate the object.
// We need to overwrite the object with a filler that
// contains no interior pointers.
MemRegion mr((HeapWord*)new_obj, new_obj_size);
// Clean this up and move to oopFactory (see bug 4718422)
SharedHeap::fill_region_with_object(mr);
}
} else {
if (!_young_lab.unallocate_object(new_obj)) {
// The promotion lab failed to unallocate the object.
// We need to overwrite the object with a filler that
// contains no interior pointers.
MemRegion mr((HeapWord*)new_obj, new_obj_size);
// Clean this up and move to oopFactory (see bug 4718422)
SharedHeap::fill_region_with_object(mr);
CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
}
} else if (!_young_lab.unallocate_object(new_obj)) {
CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
}
// don't update this before the unallocation!

View File

@ -76,8 +76,8 @@ void MutableNUMASpace::ensure_parsability() {
MutableSpace *s = ls->space();
if (s->top() < top()) { // For all spaces preceeding the one containing top()
if (s->free_in_words() > 0) {
SharedHeap::fill_region_with_object(MemRegion(s->top(), s->end()));
size_t area_touched_words = pointer_delta(s->end(), s->top());
CollectedHeap::fill_with_object(s->top(), area_touched_words);
#ifndef ASSERT
if (!ZapUnusedHeapArea) {
area_touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)),
@ -686,11 +686,11 @@ void MutableNUMASpace::set_top(HeapWord* value) {
// a minimal object; assuming that's not the last chunk in which case we don't care.
if (i < lgrp_spaces()->length() - 1) {
size_t remainder = pointer_delta(s->end(), value);
const size_t minimal_object_size = oopDesc::header_size();
if (remainder < minimal_object_size && remainder > 0) {
// Add a filler object of a minimal size, it will cross the chunk boundary.
SharedHeap::fill_region_with_object(MemRegion(value, minimal_object_size));
value += minimal_object_size;
const size_t min_fill_size = CollectedHeap::min_fill_size();
if (remainder < min_fill_size && remainder > 0) {
// Add a minimum size filler object; it will cross the chunk boundary.
CollectedHeap::fill_with_object(value, min_fill_size);
value += min_fill_size;
assert(!s->contains(value), "Should be in the next chunk");
// Restart the loop from the same chunk, since the value has moved
// to the next one.

View File

@ -30,12 +30,21 @@
int CollectedHeap::_fire_out_of_memory_count = 0;
#endif
size_t CollectedHeap::_filler_array_max_size = 0;
// Memory state functions.
CollectedHeap::CollectedHeap() :
_reserved(), _barrier_set(NULL), _is_gc_active(false),
_total_collections(0), _total_full_collections(0),
_gc_cause(GCCause::_no_gc), _gc_lastcause(GCCause::_no_gc) {
CollectedHeap::CollectedHeap()
{
const size_t max_len = size_t(arrayOopDesc::max_array_length(T_INT));
const size_t elements_per_word = HeapWordSize / sizeof(jint);
_filler_array_max_size = align_object_size(filler_array_hdr_size() +
max_len * elements_per_word);
_barrier_set = NULL;
_is_gc_active = false;
_total_collections = _total_full_collections = 0;
_gc_cause = _gc_lastcause = GCCause::_no_gc;
NOT_PRODUCT(_promotion_failure_alot_count = 0;)
NOT_PRODUCT(_promotion_failure_alot_gc_number = 0;)
@ -128,6 +137,94 @@ HeapWord* CollectedHeap::allocate_from_tlab_slow(Thread* thread, size_t size) {
return obj;
}
size_t CollectedHeap::filler_array_hdr_size() {
return size_t(arrayOopDesc::header_size(T_INT));
}
size_t CollectedHeap::filler_array_min_size() {
return align_object_size(filler_array_hdr_size());
}
size_t CollectedHeap::filler_array_max_size() {
return _filler_array_max_size;
}
#ifdef ASSERT
void CollectedHeap::fill_args_check(HeapWord* start, size_t words)
{
assert(words >= min_fill_size(), "too small to fill");
assert(words % MinObjAlignment == 0, "unaligned size");
assert(Universe::heap()->is_in_reserved(start), "not in heap");
assert(Universe::heap()->is_in_reserved(start + words - 1), "not in heap");
}
void CollectedHeap::zap_filler_array(HeapWord* start, size_t words)
{
if (ZapFillerObjects) {
Copy::fill_to_words(start + filler_array_hdr_size(),
words - filler_array_hdr_size(), 0XDEAFBABE);
}
}
#endif // ASSERT
void
CollectedHeap::fill_with_array(HeapWord* start, size_t words)
{
assert(words >= filler_array_min_size(), "too small for an array");
assert(words <= filler_array_max_size(), "too big for a single object");
const size_t payload_size = words - filler_array_hdr_size();
const size_t len = payload_size * HeapWordSize / sizeof(jint);
// Set the length first for concurrent GC.
((arrayOop)start)->set_length((int)len);
post_allocation_setup_common(Universe::intArrayKlassObj(), start, words);
DEBUG_ONLY(zap_filler_array(start, words);)
}
void
CollectedHeap::fill_with_object_impl(HeapWord* start, size_t words)
{
assert(words <= filler_array_max_size(), "too big for a single object");
if (words >= filler_array_min_size()) {
fill_with_array(start, words);
} else if (words > 0) {
assert(words == min_fill_size(), "unaligned size");
post_allocation_setup_common(SystemDictionary::object_klass(), start,
words);
}
}
void CollectedHeap::fill_with_object(HeapWord* start, size_t words)
{
DEBUG_ONLY(fill_args_check(start, words);)
HandleMark hm; // Free handles before leaving.
fill_with_object_impl(start, words);
}
void CollectedHeap::fill_with_objects(HeapWord* start, size_t words)
{
DEBUG_ONLY(fill_args_check(start, words);)
HandleMark hm; // Free handles before leaving.
#ifdef LP64
// A single array can fill ~8G, so multiple objects are needed only in 64-bit.
// First fill with arrays, ensuring that any remaining space is big enough to
// fill. The remainder is filled with a single object.
const size_t min = min_fill_size();
const size_t max = filler_array_max_size();
while (words > max) {
const size_t cur = words - max >= min ? max : max - min;
fill_with_array(start, cur);
start += cur;
words -= cur;
}
#endif
fill_with_object_impl(start, words);
}
oop CollectedHeap::new_store_barrier(oop new_obj) {
// %%% This needs refactoring. (It was imported from the server compiler.)
guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported");

View File

@ -47,6 +47,9 @@ class CollectedHeap : public CHeapObj {
static int _fire_out_of_memory_count;
#endif
// Used for filler objects (static, but initialized in ctor).
static size_t _filler_array_max_size;
protected:
MemRegion _reserved;
BarrierSet* _barrier_set;
@ -119,6 +122,21 @@ class CollectedHeap : public CHeapObj {
// Clears an allocated object.
inline static void init_obj(HeapWord* obj, size_t size);
// Filler object utilities.
static inline size_t filler_array_hdr_size();
static inline size_t filler_array_min_size();
static inline size_t filler_array_max_size();
DEBUG_ONLY(static void fill_args_check(HeapWord* start, size_t words);)
DEBUG_ONLY(static void zap_filler_array(HeapWord* start, size_t words);)
// Fill with a single array; caller must ensure filler_array_min_size() <=
// words <= filler_array_max_size().
static inline void fill_with_array(HeapWord* start, size_t words);
// Fill with a single object (either an int array or a java.lang.Object).
static inline void fill_with_object_impl(HeapWord* start, size_t words);
// Verification functions
virtual void check_for_bad_heap_word_value(HeapWord* addr, size_t size)
PRODUCT_RETURN;
@ -294,6 +312,27 @@ class CollectedHeap : public CHeapObj {
// The boundary between a "large" and "small" array of primitives, in words.
virtual size_t large_typearray_limit() = 0;
// Utilities for turning raw memory into filler objects.
//
// min_fill_size() is the smallest region that can be filled.
// fill_with_objects() can fill arbitrary-sized regions of the heap using
// multiple objects. fill_with_object() is for regions known to be smaller
// than the largest array of integers; it uses a single object to fill the
// region and has slightly less overhead.
static size_t min_fill_size() {
return size_t(align_object_size(oopDesc::header_size()));
}
static void fill_with_objects(HeapWord* start, size_t words);
static void fill_with_object(HeapWord* start, size_t words);
static void fill_with_object(MemRegion region) {
fill_with_object(region.start(), region.word_size());
}
static void fill_with_object(HeapWord* start, HeapWord* end) {
fill_with_object(start, pointer_delta(end, start));
}
// Some heaps may offer a contiguous region for shared non-blocking
// allocation, via inlined code (by exporting the address of the top and
// end fields defining the extent of the contiguous allocation region.)

View File

@ -34,7 +34,6 @@ void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
HeapWord* objPtr,
size_t size) {
oop obj = (oop)objPtr;
assert(obj != NULL, "NULL object pointer");
@ -44,9 +43,6 @@ void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
// May be bootstrapping
obj->set_mark(markOopDesc::prototype());
}
// support low memory notifications (no-op if not enabled)
LowMemoryDetector::detect_low_memory_for_collected_pools();
}
void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
@ -65,6 +61,9 @@ void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
// Support for jvmti and dtrace
inline void post_allocation_notify(KlassHandle klass, oop obj) {
// support low memory notifications (no-op if not enabled)
LowMemoryDetector::detect_low_memory_for_collected_pools();
// support for JVMTI VMObjectAlloc event (no-op if not enabled)
JvmtiExport::vm_object_alloc_event_collector(obj);

View File

@ -28,6 +28,7 @@ collectedHeap.cpp collectedHeap.hpp
collectedHeap.cpp collectedHeap.inline.hpp
collectedHeap.cpp init.hpp
collectedHeap.cpp oop.inline.hpp
collectedHeap.cpp systemDictionary.hpp
collectedHeap.cpp thread_<os_family>.inline.hpp
collectedHeap.hpp allocation.hpp

View File

@ -283,7 +283,7 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
} 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.

View File

@ -428,7 +428,7 @@ public:
}
// 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;

View File

@ -26,20 +26,24 @@
#include "incls/_permGen.cpp.incl"
HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) {
MutexLocker ml(Heap_lock);
GCCause::Cause next_cause = GCCause::_permanent_generation_full;
GCCause::Cause prev_cause = GCCause::_no_gc;
unsigned int gc_count_before, full_gc_count_before;
HeapWord* obj;
for (;;) {
HeapWord* obj = gen->allocate(size, false);
if (obj != NULL) {
{
MutexLocker ml(Heap_lock);
if ((obj = gen->allocate(size, false)) != NULL) {
return obj;
}
if (gen->capacity() < _capacity_expansion_limit ||
prev_cause != GCCause::_no_gc) {
obj = gen->expand_and_allocate(size, false);
}
if (obj == NULL && prev_cause != GCCause::_last_ditch_collection) {
if (obj != NULL || prev_cause == GCCause::_last_ditch_collection) {
return obj;
}
if (GC_locker::is_active_and_needs_gc()) {
// If this thread is not in a jni critical section, we stall
// the requestor until the critical section has cleared and
@ -61,12 +65,12 @@ HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) {
return NULL;
}
}
// Read the GC count while holding the Heap_lock
unsigned int gc_count_before = SharedHeap::heap()->total_collections();
unsigned int full_gc_count_before = SharedHeap::heap()->total_full_collections();
{
MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back
gc_count_before = SharedHeap::heap()->total_collections();
full_gc_count_before = SharedHeap::heap()->total_full_collections();
}
// Give up heap lock above, VMThread::execute below gets it back
VM_GenCollectForPermanentAllocation op(size, gc_count_before, full_gc_count_before,
next_cause);
VMThread::execute(&op);
@ -80,12 +84,8 @@ HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) {
if (obj != NULL) {
return obj;
}
}
prev_cause = next_cause;
next_cause = GCCause::_last_ditch_collection;
} else {
return obj;
}
}
}

View File

@ -248,46 +248,6 @@ void SharedHeap::ref_processing_init() {
perm_gen()->ref_processor_init();
}
void SharedHeap::fill_region_with_object(MemRegion mr) {
// Disable the posting of JVMTI VMObjectAlloc events as we
// don't want the filling of tlabs with filler arrays to be
// reported to the profiler.
NoJvmtiVMObjectAllocMark njm;
// Disable low memory detector because there is no real allocation.
LowMemoryDetectorDisabler lmd_dis;
// It turns out that post_allocation_setup_array takes a handle, so the
// call below contains an implicit conversion. Best to free that handle
// as soon as possible.
HandleMark hm;
size_t word_size = mr.word_size();
size_t aligned_array_header_size =
align_object_size(typeArrayOopDesc::header_size(T_INT));
if (word_size >= aligned_array_header_size) {
const size_t array_length =
pointer_delta(mr.end(), mr.start()) -
typeArrayOopDesc::header_size(T_INT);
const size_t array_length_words =
array_length * (HeapWordSize/sizeof(jint));
post_allocation_setup_array(Universe::intArrayKlassObj(),
mr.start(),
mr.word_size(),
(int)array_length_words);
#ifdef ASSERT
HeapWord* elt_words = (mr.start() + typeArrayOopDesc::header_size(T_INT));
Copy::fill_to_words(elt_words, array_length, 0xDEAFBABE);
#endif
} else {
assert(word_size == (size_t)oopDesc::header_size(), "Unaligned?");
post_allocation_setup_obj(SystemDictionary::object_klass(),
mr.start(),
mr.word_size());
}
}
// Some utilities.
void SharedHeap::print_size_transition(outputStream* out,
size_t bytes_before,

View File

@ -108,14 +108,6 @@ public:
void set_perm(PermGen* perm_gen) { _perm_gen = perm_gen; }
// A helper function that fills a region of the heap with
// with a single object.
static void fill_region_with_object(MemRegion mr);
// Minimum garbage fill object size
static size_t min_fill_size() { return (size_t)align_object_size(oopDesc::header_size()); }
static size_t min_fill_size_in_bytes() { return min_fill_size() * HeapWordSize; }
// This function returns the "GenRemSet" object that allows us to scan
// generations; at least the perm gen, possibly more in a fully
// generational heap.

View File

@ -409,19 +409,9 @@ bool CompactibleSpace::insert_deadspace(size_t& allowed_deadspace_words,
HeapWord* q, size_t deadlength) {
if (allowed_deadspace_words >= deadlength) {
allowed_deadspace_words -= deadlength;
oop(q)->set_mark(markOopDesc::prototype()->set_marked());
const size_t min_int_array_size = typeArrayOopDesc::header_size(T_INT);
if (deadlength >= min_int_array_size) {
oop(q)->set_klass(Universe::intArrayKlassObj());
typeArrayOop(q)->set_length((int)((deadlength - min_int_array_size)
* (HeapWordSize/sizeof(jint))));
} else {
assert((int) deadlength == instanceOopDesc::header_size(),
"size for smallest fake dead object doesn't match");
oop(q)->set_klass(SystemDictionary::object_klass());
}
assert((int) deadlength == oop(q)->size(),
"make sure size for fake dead object match");
CollectedHeap::fill_with_object(q, deadlength);
oop(q)->set_mark(oop(q)->mark()->set_marked());
assert((int) deadlength == oop(q)->size(), "bad filler object size");
// Recall that we required "q == compaction_top".
return true;
} else {

View File

@ -387,7 +387,7 @@ void TenuredGeneration::par_promote_alloc_undo(int thread_num,
"should contain whole object");
buf->undo_allocation(obj, word_sz);
} else {
SharedHeap::fill_region_with_object(MemRegion(obj, word_sz));
CollectedHeap::fill_with_object(obj, word_sz);
}
}

View File

@ -100,8 +100,7 @@ void ThreadLocalAllocBuffer::accumulate_statistics() {
void ThreadLocalAllocBuffer::make_parsable(bool retire) {
if (end() != NULL) {
invariants();
MemRegion mr(top(), hard_end());
SharedHeap::fill_region_with_object(mr);
CollectedHeap::fill_with_object(top(), hard_end());
if (retire || ZeroTLAB) { // "Reset" the TLAB
set_start(NULL);

View File

@ -274,7 +274,6 @@ void Universe::genesis(TRAPS) {
_the_array_interfaces_array = oopFactory::new_system_objArray(2, CHECK);
_vm_exception = oopFactory::new_symbol("vm exception holder", CHECK);
} else {
FileMapInfo *mapinfo = FileMapInfo::current_info();
char* buffer = mapinfo->region_base(CompactingPermGenGen::md);
void** vtbl_list = (void**)buffer;

View File

@ -92,6 +92,7 @@ class LatestMethodOopCache : public CommonMethodOopCache {
class Universe: AllStatic {
// Ugh. Universe is much too friendly.
friend class MarkSweep;
friend class oopDesc;
friend class ClassLoader;

View File

@ -96,19 +96,20 @@ class arrayOopDesc : public oopDesc {
: typesize_in_bytes/HeapWordSize);
}
// This method returns the maximum length that can passed into
// typeArrayOop::object_size(scale, length, header_size) without causing an
// overflow. We substract an extra 2*wordSize to guard against double word
// alignments. It gets the scale from the type2aelembytes array.
// Return the maximum length of an array of BasicType. The length can passed
// to typeArrayOop::object_size(scale, length, header_size) without causing an
// overflow.
static int32_t max_array_length(BasicType type) {
assert(type >= 0 && type < T_CONFLICT, "wrong type");
assert(type2aelembytes(type) != 0, "wrong type");
// We use max_jint, since object_size is internally represented by an 'int'
// This gives us an upper bound of max_jint words for the size of the oop.
int32_t max_words = (max_jint - header_size(type) - 2);
int elembytes = type2aelembytes(type);
jlong len = ((jlong)max_words * HeapWordSize) / elembytes;
return (len > max_jint) ? max_jint : (int32_t)len;
const int bytes_per_element = type2aelembytes(type);
if (bytes_per_element < HeapWordSize) {
return max_jint;
}
const int32_t max_words = align_size_down(max_jint, MinObjAlignment);
const int32_t max_element_words = max_words - header_size(type);
const int32_t words_per_element = bytes_per_element >> LogHeapWordSize;
return max_element_words / words_per_element;
}
};

View File

@ -36,13 +36,14 @@ bool typeArrayKlass::compute_is_subtype_of(klassOop k) {
return element_type() == tak->element_type();
}
klassOop typeArrayKlass::create_klass(BasicType type, int scale, TRAPS) {
klassOop typeArrayKlass::create_klass(BasicType type, int scale,
const char* name_str, TRAPS) {
typeArrayKlass o;
symbolHandle sym(symbolOop(NULL));
// bootstrapping: don't create sym if symbolKlass not created yet
if (Universe::symbolKlassObj() != NULL) {
sym = oopFactory::new_symbol_handle(external_name(type), CHECK_NULL);
if (Universe::symbolKlassObj() != NULL && name_str != NULL) {
sym = oopFactory::new_symbol_handle(name_str, CHECK_NULL);
}
KlassHandle klassklass (THREAD, Universe::typeArrayKlassKlassObj());

View File

@ -39,7 +39,11 @@ class typeArrayKlass : public arrayKlass {
// klass allocation
DEFINE_ALLOCATE_PERMANENT(typeArrayKlass);
static klassOop create_klass(BasicType type, int scale, TRAPS);
static klassOop create_klass(BasicType type, int scale, const char* name_str,
TRAPS);
static inline klassOop create_klass(BasicType type, int scale, TRAPS) {
return create_klass(type, scale, external_name(type), CHECK_NULL);
}
int oop_size(oop obj) const;
int klass_oop_size() const { return object_size(); }

View File

@ -2192,6 +2192,9 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
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: {

View File

@ -1724,6 +1724,13 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) {
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());

View File

@ -2173,7 +2173,8 @@ static char* get_bad_address() {
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;

View File

@ -444,9 +444,9 @@ char* SysClassPath::add_jars_to_path(char* path, const char* directory) {
}
// 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 @@ static bool atomll(const char *s, jlong* result) {
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 @@ static bool atomll(const char *s, jlong* result) {
}
}
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_fp_numeric_flag(char* name, char* value, FlagValueOrigin origin)
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 @@ static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) {
value++;
is_neg = true;
}
if (!atomll(value, &v)) {
if (!atomull(value, &v)) {
return false;
}
intx_v = (intx) v;
@ -1517,6 +1522,16 @@ bool Arguments::check_vm_args_consistency() {
MarkSweepAlwaysCompactCount = 1; // Move objects every gc.
}
if (UseParallelOldGC && ParallelOldGCSplitALot) {
// Settings to encourage splitting.
if (!FLAG_IS_CMDLINE(NewRatio)) {
FLAG_SET_CMDLINE(intx, NewRatio, 2);
}
if (!FLAG_IS_CMDLINE(ScavengeBeforeFullGC)) {
FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
}
}
status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
status = status && verify_percentage(GCTimeLimit, "GCTimeLimit");
if (GCTimeLimit == 100) {
@ -1667,9 +1682,9 @@ static bool match_option(const JavaVMOption* option, const char** names, const c
}
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);
}
@ -1847,7 +1862,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
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(),
@ -1859,7 +1874,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
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(),
@ -1872,7 +1887,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
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(),
@ -1905,7 +1920,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
}
// -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(),
@ -1921,9 +1936,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
// 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",
@ -2228,7 +2243,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} 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(),
@ -2283,7 +2298,7 @@ SOLARIS_ONLY(
"-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(),
@ -2291,13 +2306,13 @@ SOLARIS_ONLY(
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(),
@ -2305,7 +2320,7 @@ SOLARIS_ONLY(
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");

View File

@ -339,9 +339,9 @@ class Arguments : AllStatic {
}
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);

View File

@ -625,6 +625,9 @@ class CommandLineFlags {
develop(bool, CheckZapUnusedHeapArea, false, \
"Check zapping of unused heap space") \
\
develop(bool, ZapFillerObjects, trueInDebug, \
"Zap filler objects with 0xDEAFBABE") \
\
develop(bool, PrintVMMessages, true, \
"Print vm messages on console") \
\
@ -818,7 +821,7 @@ class CommandLineFlags {
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, \
@ -1200,11 +1203,12 @@ class CommandLineFlags {
product(uintx, ParallelCMSThreads, 0, \
"Max number of threads CMS will use for concurrent work") \
\
develop(bool, ParallelOldMTUnsafeMarkBitMap, false, \
"Use the Parallel Old MT unsafe in marking the bitmap") \
develop(bool, ParallelOldGCSplitALot, false, \
"Provoke splitting (copying data from a young gen space to" \
"multiple destination spaces)") \
\
develop(bool, ParallelOldMTUnsafeUpdateLiveData, false, \
"Use the Parallel Old MT unsafe in update of live size") \
develop(uintx, ParallelOldGCSplitInterval, 3, \
"How often to provoke splitting a young gen space") \
\
develop(bool, TraceRegionTasksQueuing, false, \
"Trace the queuing of the region tasks") \

View File

@ -504,7 +504,7 @@ class SignatureChekker : public SignatureIterator {
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);
bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true);
if (CheckJNICalls && bad) {
ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
}

View File

@ -932,8 +932,9 @@ void os::serialize_thread_states() {
// 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);
}

View File

@ -208,7 +208,7 @@ class os: AllStatic {
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);

View File

@ -3363,13 +3363,13 @@ void ObjectMonitor::ExitEpilog (Thread * Self, ObjectWaiter * Wakee) {
// 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);
}

View File

@ -694,10 +694,10 @@ JVM_ENTRY(jlong, jmm_SetPoolThreshold(JNIEnv* env, jobject obj, jmmThresholdType
-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));

View File

@ -332,6 +332,8 @@ void VMError::report(outputStream* st) {
// 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(),

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -16,3 +16,4 @@ e9f750f0a3a00413a7b77028b2ecdabb7129ae32 jdk7-b38
831b80be6cea8e7d7da197ccdac5fd4c701a5033 jdk7-b39
54946f466e2c047c44c903f1bec400b685c2508e jdk7-b40
0758bd3e2852e4f931ba211cc4d48f589450eeb4 jdk7-b41
036e0dca841a5a17f784d15c86a9da88d2a6f1e6 jdk7-b42

View File

@ -16,3 +16,4 @@ a2a6f9edf761934faf59ea60d7fe7178371302cd jdk7-b37
077bc9b1b035a409a76bd5366f73ed9dd9846934 jdk7-b39
70a6ac6dd737fe45c2fadb57646195b2b4fe269d jdk7-b40
a8379d24aa03386610169cb0f4e4b8ed266a2e8d jdk7-b41
621c02d83abc850c170fb6726d57b19f1eaf5033 jdk7-b42

View File

@ -407,6 +407,7 @@ SUNWprivate_1.1 {
Java_sun_java2d_x11_X11SurfaceData_initSurface;
Java_sun_java2d_x11_X11SurfaceData_isDrawableValid;
Java_sun_java2d_x11_X11SurfaceData_isDgaAvailable;
Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable;
Java_sun_java2d_x11_X11SurfaceData_setInvalid;
Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface;
Java_sun_java2d_x11_X11SurfaceData_XCreateGC;

View File

@ -337,6 +337,7 @@ SUNWprivate_1.1 {
Java_sun_java2d_x11_X11SurfaceData_initIDs;
Java_sun_java2d_x11_X11SurfaceData_isDrawableValid;
Java_sun_java2d_x11_X11SurfaceData_isDgaAvailable;
Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable;
Java_sun_java2d_x11_X11SurfaceData_initOps;
Java_sun_java2d_x11_X11SurfaceData_initSurface;
Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface;

View File

@ -44,7 +44,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import javax.imageio.IIOException;
@ -57,6 +56,7 @@ import javax.imageio.stream.ImageInputStream;
import com.sun.imageio.plugins.common.InputStreamAdapter;
import com.sun.imageio.plugins.common.ReaderUtil;
import com.sun.imageio.plugins.common.SubImageInputStream;
import java.io.ByteArrayOutputStream;
import sun.awt.image.ByteInterleavedRaster;
class PNGImageDataEnumeration implements Enumeration {
@ -207,6 +207,15 @@ public class PNGImageReader extends ImageReader {
resetStreamSettings();
}
private String readNullTerminatedString(String charset) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b;
while ((b = stream.read()) != 0) {
baos.write(b);
}
return new String(baos.toByteArray(), charset);
}
private String readNullTerminatedString() throws IOException {
StringBuilder b = new StringBuilder();
int c;
@ -445,26 +454,27 @@ public class PNGImageReader extends ImageReader {
metadata.iTXt_keyword.add(keyword);
int compressionFlag = stream.readUnsignedByte();
metadata.iTXt_compressionFlag.add(new Integer(compressionFlag));
metadata.iTXt_compressionFlag.add(Boolean.valueOf(compressionFlag == 1));
int compressionMethod = stream.readUnsignedByte();
metadata.iTXt_compressionMethod.add(new Integer(compressionMethod));
metadata.iTXt_compressionMethod.add(Integer.valueOf(compressionMethod));
String languageTag = readNullTerminatedString();
String languageTag = readNullTerminatedString("UTF8");
metadata.iTXt_languageTag.add(languageTag);
String translatedKeyword = stream.readUTF();
String translatedKeyword =
readNullTerminatedString("UTF8");
metadata.iTXt_translatedKeyword.add(translatedKeyword);
stream.skipBytes(1); // Null separator
String text;
if (compressionFlag == 1) { // Decompress the text
long pos = stream.getStreamPosition();
byte[] b = new byte[(int)(chunkStart + chunkLength - pos)];
stream.readFully(b);
text = inflate(b);
if (compressionFlag == 1) { // Decompress the text
text = new String(inflate(b), "UTF8");
} else {
text = stream.readUTF();
text = new String(b, "UTF8");
}
metadata.iTXt_text.add(text);
}
@ -613,15 +623,20 @@ public class PNGImageReader extends ImageReader {
metadata.tRNS_present = true;
}
private static String inflate(byte[] b) throws IOException {
private static byte[] inflate(byte[] b) throws IOException {
InputStream bais = new ByteArrayInputStream(b);
InputStream iis = new InflaterInputStream(bais);
StringBuilder sb = new StringBuilder(80);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int c;
try {
while ((c = iis.read()) != -1) {
sb.append((char)c);
baos.write(c);
}
return sb.toString();
} finally {
iis.close();
}
return baos.toByteArray();
}
private void parse_zTXt_chunk(int chunkLength) throws IOException {
@ -633,7 +648,7 @@ public class PNGImageReader extends ImageReader {
byte[] b = new byte[chunkLength - keyword.length() - 2];
stream.readFully(b);
metadata.zTXt_text.add(inflate(b));
metadata.zTXt_text.add(new String(inflate(b)));
}
private void readMetadata() throws IIOException {
@ -1244,13 +1259,26 @@ public class PNGImageReader extends ImageReader {
destinationBands = param.getDestinationBands();
destinationOffset = param.getDestinationOffset();
}
Inflater inf = null;
try {
stream.seek(imageStartPosition);
Enumeration e = new PNGImageDataEnumeration(stream);
InputStream is = new SequenceInputStream(e);
is = new InflaterInputStream(is, new Inflater());
/* InflaterInputStream uses an Inflater instance which consumes
* native (non-GC visible) resources. This is normally implicitly
* freed when the stream is closed. However since the
* InflaterInputStream wraps a client-supplied input stream,
* we cannot close it.
* But the app may depend on GC finalization to close the stream.
* Therefore to ensure timely freeing of native resources we
* explicitly create the Inflater instance and free its resources
* when we are done with the InflaterInputStream by calling
* inf.end();
*/
inf = new Inflater();
is = new InflaterInputStream(is, inf);
is = new BufferedInputStream(is);
this.pixelStream = new DataInputStream(is);
@ -1283,6 +1311,10 @@ public class PNGImageReader extends ImageReader {
}
} catch (IOException e) {
throw new IIOException("Error reading PNG image data", e);
} finally {
if (inf != null) {
inf.end();
}
}
}

View File

@ -244,6 +244,7 @@ final class IDATOutputStream extends ImageOutputStreamImpl {
}
public void finish() throws IOException {
try {
if (!def.finished()) {
def.finish();
while (!def.finished()) {
@ -251,6 +252,9 @@ final class IDATOutputStream extends ImageOutputStreamImpl {
}
}
finishChunk();
} finally {
def.end();
}
}
protected void finalize() throws Throwable {
@ -667,13 +671,13 @@ public class PNGImageWriter extends ImageWriter {
}
}
private byte[] deflate(String s) throws IOException {
private byte[] deflate(byte[] b) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(baos);
int len = s.length();
int len = b.length;
for (int i = 0; i < len; i++) {
dos.write((int)s.charAt(i));
dos.write((int)(0xff & b[i]));
}
dos.close();
@ -681,38 +685,37 @@ public class PNGImageWriter extends ImageWriter {
}
private void write_iTXt() throws IOException {
Iterator keywordIter = metadata.iTXt_keyword.iterator();
Iterator flagIter = metadata.iTXt_compressionFlag.iterator();
Iterator methodIter = metadata.iTXt_compressionMethod.iterator();
Iterator languageIter = metadata.iTXt_languageTag.iterator();
Iterator translatedKeywordIter =
Iterator<String> keywordIter = metadata.iTXt_keyword.iterator();
Iterator<Boolean> flagIter = metadata.iTXt_compressionFlag.iterator();
Iterator<Integer> methodIter = metadata.iTXt_compressionMethod.iterator();
Iterator<String> languageIter = metadata.iTXt_languageTag.iterator();
Iterator<String> translatedKeywordIter =
metadata.iTXt_translatedKeyword.iterator();
Iterator textIter = metadata.iTXt_text.iterator();
Iterator<String> textIter = metadata.iTXt_text.iterator();
while (keywordIter.hasNext()) {
ChunkStream cs = new ChunkStream(PNGImageReader.iTXt_TYPE, stream);
String keyword = (String)keywordIter.next();
cs.writeBytes(keyword);
cs.writeBytes(keywordIter.next());
cs.writeByte(0);
int flag = ((Integer)flagIter.next()).intValue();
cs.writeByte(flag);
int method = ((Integer)methodIter.next()).intValue();
cs.writeByte(method);
Boolean compressed = flagIter.next();
cs.writeByte(compressed ? 1 : 0);
String languageTag = (String)languageIter.next();
cs.writeBytes(languageTag);
cs.writeByte(methodIter.next().intValue());
cs.writeBytes(languageIter.next());
cs.writeByte(0);
String translatedKeyword = (String)translatedKeywordIter.next();
cs.writeBytes(translatedKeyword);
cs.write(translatedKeywordIter.next().getBytes("UTF8"));
cs.writeByte(0);
String text = (String)textIter.next();
if (flag == 1) {
cs.write(deflate(text));
String text = textIter.next();
if (compressed) {
cs.write(deflate(text.getBytes("UTF8")));
} else {
cs.writeUTF(text);
cs.write(text.getBytes("UTF8"));
}
cs.finish();
}
@ -733,7 +736,7 @@ public class PNGImageWriter extends ImageWriter {
cs.writeByte(compressionMethod);
String text = (String)textIter.next();
cs.write(deflate(text));
cs.write(deflate(text.getBytes()));
cs.finish();
}
}
@ -928,7 +931,7 @@ public class PNGImageWriter extends ImageWriter {
// Use sourceXOffset, etc.
private void write_IDAT(RenderedImage image) throws IOException {
IDATOutputStream ios = new IDATOutputStream(stream, 32768);
try {
if (metadata.IHDR_interlaceMethod == 1) {
for (int i = 0; i < 7; i++) {
encodePass(ios, image,
@ -943,9 +946,10 @@ public class PNGImageWriter extends ImageWriter {
} else {
encodePass(ios, image, 0, 0, 1, 1);
}
} finally {
ios.finish();
}
}
private void writeIEND() throws IOException {
ChunkStream cs = new ChunkStream(PNGImageReader.IEND_TYPE, stream);

View File

@ -174,12 +174,12 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
public byte[] iCCP_compressedProfile;
// iTXt chunk
public ArrayList iTXt_keyword = new ArrayList(); // Strings
public ArrayList iTXt_compressionFlag = new ArrayList(); // Integers
public ArrayList iTXt_compressionMethod = new ArrayList(); // Integers
public ArrayList iTXt_languageTag = new ArrayList(); // Strings
public ArrayList iTXt_translatedKeyword = new ArrayList(); // Strings
public ArrayList iTXt_text = new ArrayList(); // Strings
public ArrayList<String> iTXt_keyword = new ArrayList<String>();
public ArrayList<Boolean> iTXt_compressionFlag = new ArrayList<Boolean>();
public ArrayList<Integer> iTXt_compressionMethod = new ArrayList<Integer>();
public ArrayList<String> iTXt_languageTag = new ArrayList<String>();
public ArrayList<String> iTXt_translatedKeyword = new ArrayList<String>();
public ArrayList<String> iTXt_text = new ArrayList<String>();
// pHYs chunk
public boolean pHYs_present;
@ -597,19 +597,17 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
if (iTXt_keyword.size() > 0) {
IIOMetadataNode iTXt_parent = new IIOMetadataNode("iTXt");
for (int i = 0; i < iTXt_keyword.size(); i++) {
Integer val;
IIOMetadataNode iTXt_node = new IIOMetadataNode("iTXtEntry");
iTXt_node.setAttribute("keyword", (String)iTXt_keyword.get(i));
val = (Integer)iTXt_compressionFlag.get(i);
iTXt_node.setAttribute("compressionFlag", val.toString());
val = (Integer)iTXt_compressionMethod.get(i);
iTXt_node.setAttribute("compressionMethod", val.toString());
iTXt_node.setAttribute("keyword", iTXt_keyword.get(i));
iTXt_node.setAttribute("compressionFlag",
iTXt_compressionFlag.get(i) ? "1" : "0");
iTXt_node.setAttribute("compressionMethod",
iTXt_compressionMethod.get(i).toString());
iTXt_node.setAttribute("languageTag",
(String)iTXt_languageTag.get(i));
iTXt_languageTag.get(i));
iTXt_node.setAttribute("translatedKeyword",
(String)iTXt_translatedKeyword.get(i));
iTXt_node.setAttribute("text", (String)iTXt_text.get(i));
iTXt_translatedKeyword.get(i));
iTXt_node.setAttribute("text", iTXt_text.get(i));
iTXt_parent.appendChild(iTXt_node);
}
@ -1037,11 +1035,11 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
for (int i = 0; i < iTXt_keyword.size(); i++) {
node = new IIOMetadataNode("TextEntry");
node.setAttribute("keyword", (String)iTXt_keyword.get(i));
node.setAttribute("value", (String)iTXt_text.get(i));
node.setAttribute("keyword", iTXt_keyword.get(i));
node.setAttribute("value", iTXt_text.get(i));
node.setAttribute("language",
(String)iTXt_languageTag.get(i));
if (((Integer)iTXt_compressionFlag.get(i)).intValue() == 1) {
iTXt_languageTag.get(i));
if (iTXt_compressionFlag.get(i)) {
node.setAttribute("compression", "deflate");
} else {
node.setAttribute("compression", "none");
@ -1427,11 +1425,11 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
boolean compressionFlag =
getBooleanAttribute(iTXt_node, "compressionFlag");
iTXt_compressionFlag.add(new Boolean(compressionFlag));
iTXt_compressionFlag.add(Boolean.valueOf(compressionFlag));
String compressionMethod =
getAttribute(iTXt_node, "compressionMethod");
iTXt_compressionMethod.add(compressionMethod);
iTXt_compressionMethod.add(Integer.valueOf(compressionMethod));
String languageTag =
getAttribute(iTXt_node, "languageTag");
@ -1950,13 +1948,10 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
tEXt_text.add(value);
}
} else {
int flag = compression.equals("zip") ?
1 : 0;
// Use an iTXt node
iTXt_keyword.add(keyword);
iTXt_compressionFlag.add(new Integer(flag));
iTXt_compressionMethod.add(new Integer(0));
iTXt_compressionFlag.add(Boolean.valueOf(compression.equals("zip")));
iTXt_compressionMethod.add(Integer.valueOf(0));
iTXt_languageTag.add(language);
iTXt_translatedKeyword.add(keyword); // fake it
iTXt_text.add(value);
@ -1993,12 +1988,12 @@ public class PNGMetadata extends IIOMetadata implements Cloneable {
gAMA_present = false;
hIST_present = false;
iCCP_present = false;
iTXt_keyword = new ArrayList();
iTXt_compressionFlag = new ArrayList();
iTXt_compressionMethod = new ArrayList();
iTXt_languageTag = new ArrayList();
iTXt_translatedKeyword = new ArrayList();
iTXt_text = new ArrayList();
iTXt_keyword = new ArrayList<String>();
iTXt_compressionFlag = new ArrayList<Boolean>();
iTXt_compressionMethod = new ArrayList<Integer>();
iTXt_languageTag = new ArrayList<String>();
iTXt_translatedKeyword = new ArrayList<String>();
iTXt_text = new ArrayList<String>();
pHYs_present = false;
sBIT_present = false;
sPLT_present = false;

View File

@ -117,15 +117,18 @@ public abstract class PrinterJob {
* FileOutputStream outstream;
* StreamPrintService psPrinter;
* String psMimeType = "application/postscript";
* PrinterJob pj = PrinterJob.getPrinterJob();
*
* StreamPrintServiceFactory[] factories =
* PrinterJob.lookupStreamPrintServices(psMimeType);
* if (factories.length > 0) {
* try {
* outstream = new File("out.ps");
* psPrinter = factories[0].getPrintService(fos);
* psPrinter = factories[0].getPrintService(outstream);
* // psPrinter can now be set as the service on a PrinterJob
* } catch (FileNotFoundException e) {
* pj.setPrintService(psPrinter)
* } catch (Exception e) {
* e.printStackTrace();
* }
* }
* </pre>

View File

@ -28,9 +28,7 @@ package javax.print;
import java.io.InputStream;
import java.io.IOException;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.DocAttributeSet;

View File

@ -30,7 +30,6 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Map;
/**
* Class <code>DocFlavor</code> encapsulates an object that specifies the

View File

@ -25,7 +25,6 @@
package javax.print;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.PrintJobAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.event.PrintJobAttributeListener;

View File

@ -25,11 +25,6 @@
package javax.print;
import java.util.Map;
import javax.print.attribute.Attribute;
import javax.print.event.PrintServiceAttributeListener;
/** Interface MultiPrintService is the factory for a MultiDocPrintJob.
* A MultiPrintService

View File

@ -28,7 +28,6 @@ package javax.print;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.print.attribute.AttributeSet;
import sun.awt.AppContext;

View File

@ -28,7 +28,6 @@ package javax.print.attribute;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
/**
* Class URISyntax is an abstract base class providing the common

View File

@ -25,7 +25,6 @@
package javax.print.event;
import java.util.List;
import javax.print.PrintService;
import javax.print.attribute.AttributeSetUtilities;
import javax.print.attribute.PrintServiceAttributeSet;

View File

@ -267,7 +267,9 @@ public class Decoration {
CoreMetrics cm = label.getCoreMetrics();
if (strikethrough) {
Stroke savedStroke = g2d.getStroke();
g2d.setStroke(new BasicStroke(cm.strikethroughThickness));
g2d.setStroke(new BasicStroke(cm.strikethroughThickness,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER));
float strikeY = y + cm.strikethroughOffset;
g2d.draw(new Line2D.Float(x1, strikeY, x2, strikeY));
g2d.setStroke(savedStroke);
@ -341,7 +343,7 @@ public class Decoration {
Rectangle2D visBounds = label.handleGetVisualBounds();
if (swapColors || bgPaint != null
if (swapColors || bgPaint != null || strikethrough
|| stdUnderline != null || imUnderline != null) {
float minX = 0;
@ -377,6 +379,7 @@ public class Decoration {
// NOTE: The performace of the following code may
// be very poor.
float ulThickness = cm.underlineThickness;
float ulOffset = cm.underlineOffset;
Rectangle2D lb = label.getLogicalBounds();
float x1 = x;
@ -385,12 +388,15 @@ public class Decoration {
Area area = null;
if (stdUnderline != null) {
Shape ul = stdUnderline.getUnderlineShape(ulThickness, x1, x2, y);
Shape ul = stdUnderline.getUnderlineShape(ulThickness,
x1, x2, y+ulOffset);
area = new Area(ul);
}
if (strikethrough) {
Stroke stStroke = new BasicStroke(cm.strikethroughThickness);
Stroke stStroke = new BasicStroke(cm.strikethroughThickness,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER);
float shiftY = y + cm.strikethroughOffset;
Line2D line = new Line2D.Float(x1, shiftY, x2, shiftY);
Area slArea = new Area(stStroke.createStrokedShape(line));
@ -402,7 +408,8 @@ public class Decoration {
}
if (imUnderline != null) {
Shape ul = imUnderline.getUnderlineShape(ulThickness, x1, x2, y);
Shape ul = imUnderline.getUnderlineShape(ulThickness,
x1, x2, y+ulOffset);
Area ulArea = new Area(ul);
if (area == null) {
area = ulArea;

View File

@ -3344,7 +3344,7 @@ public final class FontManager {
int fontFormat = FONTFORMAT_NONE;
int fontRank = Font2D.UNKNOWN_RANK;
if (ext.equals(".ttf") || isTTC) {
if (ext.equals(".ttf") || ext.equals(".otf") || isTTC) {
fontFormat = FONTFORMAT_TRUETYPE;
fontRank = Font2D.TTF_RANK;
} else if (ext.equals(".pfa") || ext.equals(".pfb")) {

View File

@ -90,6 +90,7 @@ public class TrueTypeFont extends FileFont {
public static final int ttcfTag = 0x74746366; // 'ttcf' - TTC file
public static final int v1ttTag = 0x00010000; // 'v1tt' - Version 1 TT font
public static final int trueTag = 0x74727565; // 'true' - Version 2 TT font
public static final int ottoTag = 0x4f54544f; // 'otto' - OpenType font
/* -- ID's used in the 'name' table */
public static final int MS_PLATFORM_ID = 3;
@ -490,6 +491,7 @@ public class TrueTypeFont extends FileFont {
case v1ttTag:
case trueTag:
case ottoTag:
break;
default:

View File

@ -126,7 +126,9 @@ abstract class Underline {
private BasicStroke createStroke(float lineThickness) {
if (dashPattern == null) {
return new BasicStroke(lineThickness);
return new BasicStroke(lineThickness,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER);
}
else {
return new BasicStroke(lineThickness,

View File

@ -812,7 +812,9 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
return(name.startsWith(".ttf", offset) ||
name.startsWith(".TTF", offset) ||
name.startsWith(".ttc", offset) ||
name.startsWith(".TTC", offset));
name.startsWith(".TTC", offset) ||
name.startsWith(".otf", offset) ||
name.startsWith(".OTF", offset));
}
}
}
@ -837,28 +839,8 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
public static class TTorT1Filter implements FilenameFilter {
public boolean accept(File dir, String name) {
/* all conveniently have the same suffix length */
int offset = name.length()-4;
if (offset <= 0) { /* must be at least A.ttf or A.pfa */
return false;
} else {
boolean isTT =
name.startsWith(".ttf", offset) ||
name.startsWith(".TTF", offset) ||
name.startsWith(".ttc", offset) ||
name.startsWith(".TTC", offset);
if (isTT) {
return true;
} else if (noType1Font) {
return false;
} else {
return(name.startsWith(".pfa", offset) ||
name.startsWith(".pfb", offset) ||
name.startsWith(".PFA", offset) ||
name.startsWith(".PFB", offset));
}
}
return SunGraphicsEnvironment.ttFilter.accept(dir, name) ||
SunGraphicsEnvironment.t1Filter.accept(dir, name);
}
}
@ -1290,6 +1272,13 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
displayChanger.notifyPaletteChanged();
}
/**
* Returns true when the display is local, false for remote displays.
*
* @return true when the display is local, false for remote displays
*/
public abstract boolean isDisplayLocal();
/*
* ----DISPLAY CHANGE SUPPORT----
*/

View File

@ -449,7 +449,8 @@ public abstract class SurfaceData
// For now the answer can only be true in the following cases:
if (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
sg2d.clipState <= SunGraphics2D.CLIP_RECTANGULAR)
sg2d.clipState <= SunGraphics2D.CLIP_RECTANGULAR &&
sg2d.surfaceData.getTransparency() == Transparency.OPAQUE)
{
if (haveLCDLoop == LCDLOOP_UNKNOWN) {
DrawGlyphListLCD loop =

View File

@ -25,17 +25,13 @@
package sun.java2d.opengl;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorModel;
import java.lang.ref.WeakReference;
import sun.awt.image.BufImgSurfaceData;
import sun.java2d.SurfaceData;
import sun.java2d.loops.Blit;
import sun.java2d.loops.CompositeType;
@ -84,6 +80,8 @@ class OGLBlitLoops {
OGLSurfaceData.PF_INT_BGR),
new OGLSwToSurfaceBlit(SurfaceType.IntBgrx,
OGLSurfaceData.PF_INT_BGRX),
new OGLSwToSurfaceBlit(SurfaceType.ThreeByteBgr,
OGLSurfaceData.PF_3BYTE_BGR),
new OGLSwToSurfaceBlit(SurfaceType.Ushort565Rgb,
OGLSurfaceData.PF_USHORT_565_RGB),
new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgb,
@ -106,6 +104,8 @@ class OGLBlitLoops {
OGLSurfaceData.PF_INT_BGR),
new OGLSwToSurfaceScale(SurfaceType.IntBgrx,
OGLSurfaceData.PF_INT_BGRX),
new OGLSwToSurfaceScale(SurfaceType.ThreeByteBgr,
OGLSurfaceData.PF_3BYTE_BGR),
new OGLSwToSurfaceScale(SurfaceType.Ushort565Rgb,
OGLSurfaceData.PF_USHORT_565_RGB),
new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgb,
@ -127,6 +127,8 @@ class OGLBlitLoops {
OGLSurfaceData.PF_INT_BGR),
new OGLSwToSurfaceTransform(SurfaceType.IntBgrx,
OGLSurfaceData.PF_INT_BGRX),
new OGLSwToSurfaceTransform(SurfaceType.ThreeByteBgr,
OGLSurfaceData.PF_3BYTE_BGR),
new OGLSwToSurfaceTransform(SurfaceType.Ushort565Rgb,
OGLSurfaceData.PF_USHORT_565_RGB),
new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgb,
@ -155,6 +157,8 @@ class OGLBlitLoops {
OGLSurfaceData.PF_INT_BGR),
new OGLSwToTextureBlit(SurfaceType.IntBgrx,
OGLSurfaceData.PF_INT_BGRX),
new OGLSwToTextureBlit(SurfaceType.ThreeByteBgr,
OGLSurfaceData.PF_3BYTE_BGR),
new OGLSwToTextureBlit(SurfaceType.Ushort565Rgb,
OGLSurfaceData.PF_USHORT_565_RGB),
new OGLSwToTextureBlit(SurfaceType.Ushort555Rgb,

View File

@ -120,6 +120,7 @@ public abstract class OGLSurfaceData extends SurfaceData
public static final int PF_USHORT_555_RGBX = 8;
public static final int PF_BYTE_GRAY = 9;
public static final int PF_USHORT_GRAY = 10;
public static final int PF_3BYTE_BGR = 11;
/**
* SurfaceTypes
@ -401,6 +402,7 @@ public abstract class OGLSurfaceData extends SurfaceData
* - the fragment shader extension is available, and
* - blending is disabled, and
* - the source color is opaque
* - and the destination is opaque
*
* Eventually, we could enhance the native OGL text rendering code
* and remove the above restrictions, but that would require significantly
@ -410,7 +412,8 @@ public abstract class OGLSurfaceData extends SurfaceData
return
graphicsConfig.isCapPresent(CAPS_EXT_LCD_SHADER) &&
sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
sg2d.paintState <= SunGraphics2D.PAINT_OPAQUECOLOR;
sg2d.paintState <= SunGraphics2D.PAINT_OPAQUECOLOR &&
sg2d.surfaceData.getTransparency() == Transparency.OPAQUE;
}
public void validatePipe(SunGraphics2D sg2d) {

View File

@ -90,7 +90,8 @@ public abstract class BufferedContext {
private Region validatedClip;
private Composite validatedComp;
private Paint validatedPaint;
private boolean isValidatedPaintAColor;
// renamed from isValidatedPaintAColor as part of a work around for 6764257
private boolean isValidatedPaintJustAColor;
private int validatedRGB;
private int validatedFlags;
private boolean xformInUse;
@ -182,7 +183,7 @@ public abstract class BufferedContext {
if (paint instanceof Color) {
// REMIND: not 30-bit friendly
int newRGB = ((Color)paint).getRGB();
if (isValidatedPaintAColor) {
if (isValidatedPaintJustAColor) {
if (newRGB != validatedRGB) {
validatedRGB = newRGB;
updatePaint = true;
@ -190,13 +191,13 @@ public abstract class BufferedContext {
} else {
validatedRGB = newRGB;
updatePaint = true;
isValidatedPaintAColor = true;
isValidatedPaintJustAColor = true;
}
} else if (validatedPaint != paint) {
updatePaint = true;
// this should be set when we are switching from paint to color
// in which case this condition will be true
isValidatedPaintAColor = false;
isValidatedPaintJustAColor = false;
}
if ((currentContext != this) ||
@ -281,7 +282,7 @@ public abstract class BufferedContext {
txChanged = true;
}
// non-Color paints may require paint revalidation
if (!isValidatedPaintAColor && txChanged) {
if (!isValidatedPaintJustAColor && txChanged) {
updatePaint = true;
}
@ -427,10 +428,12 @@ public abstract class BufferedContext {
resetTransform();
resetComposite();
resetClip();
BufferedPaints.resetPaint(rq);
invalidateSurfaces();
validatedComp = null;
validatedClip = null;
validatedPaint = null;
isValidatedPaintJustAColor = false;
xformInUse = false;
}

View File

@ -30,7 +30,6 @@ import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Transparency;

View File

@ -25,7 +25,6 @@
package sun.print;
import javax.print.DocFlavor;
import javax.print.AttributeException;
import javax.print.PrintException;
import javax.print.attribute.Attribute;

View File

@ -25,7 +25,6 @@
package sun.print;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintRequestAttribute;
/*

View File

@ -26,7 +26,6 @@
package sun.print;
import javax.print.attribute.PrintRequestAttribute;
import javax.print.attribute.standard.Media;
/*
* A class used to determine the range of pages to be printed.

View File

@ -55,6 +55,7 @@ import java.io.*;
import java.util.*;
import sun.font.FontDesignMetrics;
import sun.font.FontManager;
import sun.java2d.SunGraphicsEnvironment;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
@ -1478,22 +1479,14 @@ public class SwingUtilities2 {
* appear capable of performing gamma correction needed for LCD text.
*/
public static boolean isLocalDisplay() {
try {
// On Windows just return true. Permission to read os.name
// is granted to all code but wrapped in try to be safe.
if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS) {
return true;
boolean isLocal;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (ge instanceof SunGraphicsEnvironment) {
isLocal = ((SunGraphicsEnvironment) ge).isDisplayLocal();
} else {
isLocal = true;
}
// Else probably Solaris or Linux in which case may be remote X11
Class<?> x11Class = Class.forName("sun.awt.X11GraphicsEnvironment");
Method isDisplayLocalMethod = x11Class.getMethod(
"isDisplayLocal", new Class[0]);
return (Boolean)isDisplayLocalMethod.invoke(null, (Object[])null);
} catch (Throwable t) {
}
// If we get here we're most likely being run on some other O/S
// or we didn't properly detect Windows.
return true;
return isLocal;
}
/**

View File

@ -60,6 +60,9 @@ import java.awt.image.VolatileImage;
import java.awt.image.WritableRaster;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferShort;
import java.util.ArrayList;
import javax.swing.JComponent;
@ -84,6 +87,7 @@ public abstract class ImageTests extends GraphicsTests {
static Group.EnableSet bufimgsrcroot;
static Group imgtestroot;
static Group imgoptionsroot;
static Group imageOpRoot;
static Group imageOpOptRoot;
@ -92,6 +96,7 @@ public abstract class ImageTests extends GraphicsTests {
static Group bufImgOpTestRoot;
static Group rasterOpTestRoot;
static Option opList;
static Option doTouchSrc;
static String transNodeNames[] = {
null, "opaque", "bitmask", "translucent",
@ -105,9 +110,19 @@ public abstract class ImageTests extends GraphicsTests {
imageroot = new Group(graphicsroot, "imaging",
"Imaging Benchmarks");
imageroot.setTabbed();
imgsrcroot = new Group.EnableSet(imageroot, "src",
"Image Rendering Sources");
imgsrcroot.setBordered(true);
imgoptionsroot = new Group(imgsrcroot, "options",
"Image Source Options");
imgoptionsroot.setBordered(true);
doTouchSrc =
new Option.Toggle(imgoptionsroot, "touchsrc",
"Touch src image before every operation",
Option.Toggle.Off);
imgtestroot = new Group(imageroot, "tests",
"Image Rendering Tests");
imgtestroot.setBordered(true);
@ -131,7 +146,11 @@ public abstract class ImageTests extends GraphicsTests {
new BufImg(BufferedImage.TYPE_INT_RGB);
new BufImg(BufferedImage.TYPE_INT_ARGB);
new BufImg(BufferedImage.TYPE_BYTE_GRAY);
new BufImg(BufferedImage.TYPE_3BYTE_BGR);
new BmByteIndexBufImg();
new BufImg(BufferedImage.TYPE_INT_RGB, true);
new BufImg(BufferedImage.TYPE_INT_ARGB, true);
new BufImg(BufferedImage.TYPE_3BYTE_BGR, true);
imageOpRoot = new Group(imageroot, "imageops",
"Image Op Benchmarks");
@ -193,6 +212,7 @@ public abstract class ImageTests extends GraphicsTests {
}
public static class Context extends GraphicsTests.Context {
boolean touchSrc;
Image src;
AffineTransform tx;
}
@ -206,6 +226,7 @@ public abstract class ImageTests extends GraphicsTests {
{
super(parent, nodeName, description);
addDependency(imgsrcroot, srcFilter);
addDependency(doTouchSrc);
}
public GraphicsTests.Context createContext() {
@ -217,6 +238,7 @@ public abstract class ImageTests extends GraphicsTests {
ImageTests.Context ictx = (ImageTests.Context) ctx;
ictx.src = env.getSrcImage();
ictx.touchSrc = env.isEnabled(doTouchSrc);
}
public abstract static class TriStateImageType extends Group {
@ -272,13 +294,6 @@ public abstract class ImageTests extends GraphicsTests {
public static class CompatImg extends TriStateImageType {
int transparency;
public static String Descriptions[] = {
"Default Compatible Image",
"Opaque Compatible Image",
"Bitmask Compatible Image",
"Translucent Compatible Image",
};
public CompatImg(int transparency) {
super(imgsrcroot,
Destinations.CompatImg.ShortNames[transparency],
@ -296,6 +311,7 @@ public abstract class ImageTests extends GraphicsTests {
public static class BufImg extends TriStateImageType {
int type;
boolean unmanaged;
static int Transparencies[] = {
Transparency.TRANSLUCENT, // "custom",
@ -315,15 +331,37 @@ public abstract class ImageTests extends GraphicsTests {
};
public BufImg(int type) {
this(type, false);
}
public BufImg(int type, boolean unmanaged) {
super(bufimgsrcroot,
(unmanaged ? "unmanaged" : "") +
Destinations.BufImg.ShortNames[type],
(unmanaged ? "Unmanaged " : "") +
Destinations.BufImg.Descriptions[type],
Transparencies[type]);
this.type = type;
this.unmanaged = unmanaged;
}
public Image makeImage(TestEnvironment env, int w, int h) {
return new BufferedImage(w, h, type);
BufferedImage img = new BufferedImage(w, h, type);
if (unmanaged) {
DataBuffer db = img.getRaster().getDataBuffer();
if (db instanceof DataBufferInt) {
((DataBufferInt)db).getData();
} else if (db instanceof DataBufferShort) {
((DataBufferShort)db).getData();
} else if (db instanceof DataBufferByte) {
((DataBufferByte)db).getData();
} else {
try {
img.setAccelerationPriority(0.0f);
} catch (Throwable e) {}
}
}
return img;
}
}
@ -471,7 +509,10 @@ public abstract class ImageTests extends GraphicsTests {
g.translate(ictx.orgX, ictx.orgY);
Image src = ictx.src;
if (ictx.animate) {
if (ictx.touchSrc) {
Graphics srcG = src.getGraphics();
do {
srcG.fillRect(0, 0, 1, 1);
g.drawImage(src, x, y, null);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
@ -479,8 +520,23 @@ public abstract class ImageTests extends GraphicsTests {
} else {
do {
g.drawImage(src, x, y, null);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
} while (--numReps > 0);
}
} else {
if (ictx.touchSrc) {
Graphics srcG = src.getGraphics();
do {
srcG.fillRect(0, 0, 1, 1);
g.drawImage(src, x, y, null);
} while (--numReps > 0);
} else {
do {
g.drawImage(src, x, y, null);
} while (--numReps > 0);
}
}
g.translate(-ictx.orgX, -ictx.orgY);
}
}
@ -505,7 +561,10 @@ public abstract class ImageTests extends GraphicsTests {
Image src = ictx.src;
Color bg = Color.orange;
if (ictx.animate) {
if (ictx.touchSrc) {
Graphics srcG = src.getGraphics();
do {
srcG.fillRect(0, 0, 1, 1);
g.drawImage(src, x, y, bg, null);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
@ -513,8 +572,23 @@ public abstract class ImageTests extends GraphicsTests {
} else {
do {
g.drawImage(src, x, y, bg, null);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
} while (--numReps > 0);
}
} else {
if (ictx.touchSrc) {
Graphics srcG = src.getGraphics();
do {
srcG.fillRect(0, 0, 1, 1);
g.drawImage(src, x, y, bg, null);
} while (--numReps > 0);
} else {
do {
g.drawImage(src, x, y, bg, null);
} while (--numReps > 0);
}
}
g.translate(-ictx.orgX, -ictx.orgY);
}
}
@ -546,7 +620,10 @@ public abstract class ImageTests extends GraphicsTests {
g.translate(ictx.orgX, ictx.orgY);
Image src = ictx.src;
if (ictx.animate) {
if (ictx.touchSrc) {
Graphics srcG = src.getGraphics();
do {
srcG.fillRect(0, 0, 1, 1);
g.drawImage(src, x, y, w, h, null);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
@ -554,8 +631,23 @@ public abstract class ImageTests extends GraphicsTests {
} else {
do {
g.drawImage(src, x, y, w, h, null);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
} while (--numReps > 0);
}
} else {
Graphics srcG = src.getGraphics();
if (ictx.touchSrc) {
do {
srcG.fillRect(0, 0, 1, 1);
g.drawImage(src, x, y, w, h, null);
} while (--numReps > 0);
} else {
do {
g.drawImage(src, x, y, w, h, null);
} while (--numReps > 0);
}
}
g.translate(-ictx.orgX, -ictx.orgY);
}
}
@ -588,18 +680,37 @@ public abstract class ImageTests extends GraphicsTests {
Image src = ictx.src;
AffineTransform tx = ictx.tx;
if (ictx.animate) {
if (ictx.touchSrc) {
Graphics srcG = src.getGraphics();
do {
tx.setTransform(1.0, 0.1, 0.1, 1.0, x, y);
srcG.fillRect(0, 0, 1, 1);
g.drawImage(src, tx, null);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
} while (--numReps > 0);
} else {
do {
tx.setTransform(1.0, 0.1, 0.1, 1.0, x, y);
g.drawImage(src, tx, null);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
} while (--numReps > 0);
}
} else {
tx.setTransform(1.0, 0.1, 0.1, 1.0, x, y);
if (ictx.touchSrc) {
Graphics srcG = src.getGraphics();
do {
srcG.fillRect(0, 0, 1, 1);
g.drawImage(src, tx, null);
} while (--numReps > 0);
} else {
do {
g.drawImage(src, tx, null);
} while (--numReps > 0);
}
}
g.translate(-ictx.orgX, -ictx.orgY);
}
}
@ -736,7 +847,10 @@ public abstract class ImageTests extends GraphicsTests {
Graphics2D g2 = (Graphics2D)ictx.graphics;
g2.translate(ictx.orgX, ictx.orgY);
if (ictx.animate) {
if (ictx.touchSrc) {
Graphics gSrc = src.getGraphics();
do {
gSrc.fillRect(0, 0, 1, 1);
g2.drawImage(src, op, x, y);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
@ -744,8 +858,23 @@ public abstract class ImageTests extends GraphicsTests {
} else {
do {
g2.drawImage(src, op, x, y);
if ((x -= 3) < 0) x += ictx.maxX;
if ((y -= 1) < 0) y += ictx.maxY;
} while (--numReps > 0);
}
} else {
if (ictx.touchSrc) {
Graphics gSrc = src.getGraphics();
do {
gSrc.fillRect(0, 0, 1, 1);
g2.drawImage(src, op, x, y);
} while (--numReps > 0);
} else {
do {
g2.drawImage(src, op, x, y);
} while (--numReps > 0);
}
}
g2.translate(-ictx.orgX, -ictx.orgY);
}
}
@ -778,11 +907,19 @@ public abstract class ImageTests extends GraphicsTests {
BufferedImageOp op = ictx.bufImgOp;
BufferedImage src = ictx.bufSrc;
BufferedImage dst = ictx.bufDst;
if (ictx.touchSrc) {
Graphics gSrc = src.getGraphics();
do {
gSrc.fillRect(0, 0, 1, 1);
op.filter(src, dst);
} while (--numReps > 0);
} else {
do {
op.filter(src, dst);
} while (--numReps > 0);
}
}
}
private static class RasterOpFilter extends ImageOpTests {
private boolean cached;
@ -814,9 +951,17 @@ public abstract class ImageTests extends GraphicsTests {
RasterOp op = ictx.rasterOp;
Raster src = ictx.rasSrc;
WritableRaster dst = ictx.rasDst;
if (ictx.touchSrc) {
Graphics gSrc = ictx.bufSrc.getGraphics();
do {
gSrc.fillRect(0, 0, 1, 1);
op.filter(src, dst);
} while (--numReps > 0);
} else {
do {
op.filter(src, dst);
} while (--numReps > 0);
}
}
}
}

View File

@ -1281,7 +1281,7 @@ Java_sun_font_FreetypeFontScaler_getGlyphOutlineBoundsNative(
sunFontIDs.rect2DFloatClass,
sunFontIDs.rect2DFloatCtr4,
F26Dot6ToFloat(bbox.xMin),
F26Dot6ToFloat(bbox.yMax),
F26Dot6ToFloat(-bbox.yMax),
F26Dot6ToFloat(bbox.xMax-bbox.xMin),
F26Dot6ToFloat(bbox.yMax-bbox.yMin));
}

View File

@ -203,7 +203,24 @@ OGLBlitSwToSurface(OGLContext *oglc, SurfaceDataRasInfo *srcInfo,
j2d_glBitmap(0, 0, 0, 0, (GLfloat)dx1, (GLfloat)-dy1, NULL);
j2d_glPixelZoom(scalex, -scaley);
// in case pixel stride is not a multiple of scanline stride the copy
// has to be done line by line (see 6207877)
if (srcInfo->scanStride % srcInfo->pixelStride != 0) {
jint width = sx2-sx1;
jint height = sy2-sy1;
GLvoid *pSrc = srcInfo->rasBase;
while (height > 0) {
j2d_glDrawPixels(width, 1, pf->format, pf->type, pSrc);
j2d_glBitmap(0, 0, 0, 0, (GLfloat)0, (GLfloat)-1, NULL);
pSrc = PtrAddBytes(pSrc, srcInfo->scanStride);
height--;
}
} else {
j2d_glDrawPixels(sx2-sx1, sy2-sy1, pf->format, pf->type, srcInfo->rasBase);
}
j2d_glPixelZoom(1.0, 1.0);
if (oglc->extraAlpha != 1.0f) {
@ -250,6 +267,7 @@ OGLBlitToSurfaceViaTexture(OGLContext *oglc, SurfaceDataRasInfo *srcInfo,
jint sx, sy, sw, sh;
GLint glhint = (hint == OGLSD_XFORM_BILINEAR) ? GL_LINEAR : GL_NEAREST;
jboolean adjustAlpha = (pf != NULL && !pf->hasAlpha);
jboolean slowPath;
if (oglc->blitTextureID == 0) {
if (!OGLContext_InitBlitTileTexture(oglc)) {
@ -279,6 +297,10 @@ OGLBlitToSurfaceViaTexture(OGLContext *oglc, SurfaceDataRasInfo *srcInfo,
j2d_glPixelTransferf(GL_ALPHA_BIAS, 1.0f);
}
// in case pixel stride is not a multiple of scanline stride the copy
// has to be done line by line (see 6207877)
slowPath = srcInfo->scanStride % srcInfo->pixelStride != 0;
for (sy = sy1, dy = dy1; sy < sy2; sy += th, dy += cdh) {
sh = ((sy + th) > sy2) ? (sy2 - sy) : th;
dh = ((dy + cdh) > dy2) ? (dy2 - dy) : cdh;
@ -291,6 +313,21 @@ OGLBlitToSurfaceViaTexture(OGLContext *oglc, SurfaceDataRasInfo *srcInfo,
ty2 = ((GLdouble)sh) / th;
if (swsurface) {
if (slowPath) {
jint tmph = sh;
GLvoid *pSrc = PtrCoord(srcInfo->rasBase,
sx, srcInfo->pixelStride,
sy, srcInfo->scanStride);
while (tmph > 0) {
j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
0, sh - tmph, sw, 1,
pf->format, pf->type,
pSrc);
pSrc = PtrAddBytes(pSrc, srcInfo->scanStride);
tmph--;
}
} else {
j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
@ -298,6 +335,7 @@ OGLBlitToSurfaceViaTexture(OGLContext *oglc, SurfaceDataRasInfo *srcInfo,
0, 0, sw, sh,
pf->format, pf->type,
srcInfo->rasBase);
}
// the texture image is "right side up", so we align the
// upper-left texture corner with the upper-left quad corner
@ -356,10 +394,26 @@ OGLBlitSwToTexture(SurfaceDataRasInfo *srcInfo, OGLPixelFormat *pf,
jint dx1, jint dy1, jint dx2, jint dy2)
{
j2d_glBindTexture(dstOps->textureTarget, dstOps->textureID);
// in case pixel stride is not a multiple of scanline stride the copy
// has to be done line by line (see 6207877)
if (srcInfo->scanStride % srcInfo->pixelStride != 0) {
jint width = dx2 - dx1;
jint height = dy2 - dy1;
GLvoid *pSrc = srcInfo->rasBase;
while (height > 0) {
j2d_glTexSubImage2D(dstOps->textureTarget, 0,
dx1, dy2 - height, width, 1,
pf->format, pf->type, pSrc);
pSrc = PtrAddBytes(pSrc, srcInfo->scanStride);
height--;
}
} else {
j2d_glTexSubImage2D(dstOps->textureTarget, 0,
dx1, dy1, dx2-dx1, dy2-dy1,
pf->format, pf->type, srcInfo->rasBase);
}
}
/**
* General blit method for copying a native OpenGL surface (of type "Surface"

Some files were not shown because too many files have changed in this diff Show More