This commit is contained in:
J. Duke 2017-07-05 19:14:16 +02:00
commit 76bc84e412
645 changed files with 13551 additions and 5946 deletions

View File

@ -230,3 +230,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106 8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106
0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107 0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107
9286a6e61291246d88af713f1ef79adeea30fe2e jdk8-b108 9286a6e61291246d88af713f1ef79adeea30fe2e jdk8-b108
91f47e8da5c60de58ed195e9b57f3bf192a18f83 jdk8-b109

View File

@ -76,13 +76,13 @@ diff_text() {
TMP=1 TMP=1
if [[ "$THIS_FILE" = *"META-INF/MANIFEST.MF" ]]; then if [[ "$THIS_FILE" = *"META-INF/MANIFEST.MF" ]]; then
TMP=$(LANG=C $DIFF $OTHER_FILE $THIS_FILE | \ TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
$GREP '^[<>]' | \ $GREP '^[<>]' | \
$SED -e '/[<>] Ant-Version: Apache Ant .*/d' \ $SED -e '/[<>] Ant-Version: Apache Ant .*/d' \
-e '/[<>] Created-By: .* (Oracle Corporation).*/d') -e '/[<>] Created-By: .* (Oracle Corporation).*/d')
fi fi
if test "x$SUFFIX" = "xjava"; then if test "x$SUFFIX" = "xjava"; then
TMP=$(LANG=C $DIFF $OTHER_FILE $THIS_FILE | \ TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
$GREP '^[<>]' | \ $GREP '^[<>]' | \
$SED -e '/[<>] \* from.*\.idl/d' \ $SED -e '/[<>] \* from.*\.idl/d' \
-e '/[<>] \*.*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \ -e '/[<>] \*.*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \
@ -121,8 +121,8 @@ diff_text() {
# | $SED -e '/^#/d' -e '/^$/d' \ # | $SED -e '/^#/d' -e '/^$/d' \
# -e :a -e '/\\$/N; s/\\\n//; ta' \ # -e :a -e '/\\$/N; s/\\\n//; ta' \
# -e 's/^[ \t]*//;s/[ \t]*$//' \ # -e 's/^[ \t]*//;s/[ \t]*$//' \
# -e 's/\\=/=/' | LANG=C $SORT > $OTHER_FILE.cleaned # -e 's/\\=/=/' | LC_ALL=C $SORT > $OTHER_FILE.cleaned
TMP=$(LANG=C $DIFF $OTHER_FILE.cleaned $THIS_FILE) TMP=$(LC_ALL=C $DIFF $OTHER_FILE.cleaned $THIS_FILE)
fi fi
if test -n "$TMP"; then if test -n "$TMP"; then
echo Files $OTHER_FILE and $THIS_FILE differ echo Files $OTHER_FILE and $THIS_FILE differ
@ -410,11 +410,11 @@ compare_zip_file() {
CONTENTS_DIFF_FILE=$WORK_DIR/$ZIP_FILE.diff CONTENTS_DIFF_FILE=$WORK_DIR/$ZIP_FILE.diff
# On solaris, there is no -q option. # On solaris, there is no -q option.
if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then
LANG=C $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \ LC_ALL=C $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \
| $GREP -v -e "^<" -e "^>" -e "^Common subdirectories:" \ | $GREP -v -e "^<" -e "^>" -e "^Common subdirectories:" \
> $CONTENTS_DIFF_FILE > $CONTENTS_DIFF_FILE
else else
LANG=C $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE LC_ALL=C $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE
fi fi
ONLY_OTHER=$($GREP "^Only in $OTHER_UNZIPDIR" $CONTENTS_DIFF_FILE) ONLY_OTHER=$($GREP "^Only in $OTHER_UNZIPDIR" $CONTENTS_DIFF_FILE)
@ -459,11 +459,11 @@ compare_zip_file() {
if [ -n "$SHOW_DIFFS" ]; then if [ -n "$SHOW_DIFFS" ]; then
for i in $(cat $WORK_DIR/$ZIP_FILE.difflist) ; do for i in $(cat $WORK_DIR/$ZIP_FILE.difflist) ; do
if [ -f "${OTHER_UNZIPDIR}/$i.javap" ]; then if [ -f "${OTHER_UNZIPDIR}/$i.javap" ]; then
LANG=C $DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap
elif [ -f "${OTHER_UNZIPDIR}/$i.cleaned" ]; then elif [ -f "${OTHER_UNZIPDIR}/$i.cleaned" ]; then
LANG=C $DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i
else else
LANG=C $DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i
fi fi
done done
fi fi
@ -703,7 +703,7 @@ compare_bin_file() {
$NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this
fi fi
LANG=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff LC_ALL=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff
if [ -s $WORK_FILE_BASE.symbols.diff ]; then if [ -s $WORK_FILE_BASE.symbols.diff ]; then
SYM_MSG=" diff " SYM_MSG=" diff "
if [[ "$ACCEPTED_SYM_DIFF" != *"$BIN_FILE"* ]]; then if [[ "$ACCEPTED_SYM_DIFF" != *"$BIN_FILE"* ]]; then
@ -732,8 +732,8 @@ compare_bin_file() {
(cd $FILE_WORK_DIR && $CP $THIS_FILE . && $LDD_CMD $NAME 2</dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.this | $UNIQ > $WORK_FILE_BASE.deps.this.uniq) (cd $FILE_WORK_DIR && $CP $THIS_FILE . && $LDD_CMD $NAME 2</dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.this | $UNIQ > $WORK_FILE_BASE.deps.this.uniq)
(cd $FILE_WORK_DIR && $RM -f $NAME) (cd $FILE_WORK_DIR && $RM -f $NAME)
LANG=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this > $WORK_FILE_BASE.deps.diff LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this > $WORK_FILE_BASE.deps.diff
LANG=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq > $WORK_FILE_BASE.deps.diff.uniq LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq > $WORK_FILE_BASE.deps.diff.uniq
if [ -s $WORK_FILE_BASE.deps.diff ]; then if [ -s $WORK_FILE_BASE.deps.diff ]; then
if [ -s $WORK_FILE_BASE.deps.diff.uniq ]; then if [ -s $WORK_FILE_BASE.deps.diff.uniq ]; then
@ -768,7 +768,7 @@ compare_bin_file() {
if [ -n "$FULLDUMP_CMD" ] && [ -z "$SKIP_FULLDUMP_DIFF" ]; then if [ -n "$FULLDUMP_CMD" ] && [ -z "$SKIP_FULLDUMP_DIFF" ]; then
$FULLDUMP_CMD $OTHER_FILE > $WORK_FILE_BASE.fulldump.other 2>&1 $FULLDUMP_CMD $OTHER_FILE > $WORK_FILE_BASE.fulldump.other 2>&1
$FULLDUMP_CMD $THIS_FILE > $WORK_FILE_BASE.fulldump.this 2>&1 $FULLDUMP_CMD $THIS_FILE > $WORK_FILE_BASE.fulldump.this 2>&1
LANG=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this > $WORK_FILE_BASE.fulldump.diff LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this > $WORK_FILE_BASE.fulldump.diff
if [ -s $WORK_FILE_BASE.fulldump.diff ]; then if [ -s $WORK_FILE_BASE.fulldump.diff ]; then
ELF_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.fulldump.diff | awk '{print $5}') ELF_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.fulldump.diff | awk '{print $5}')
@ -802,7 +802,7 @@ compare_bin_file() {
$DIS_CMD $OTHER_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.other 2>&1 $DIS_CMD $OTHER_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.other 2>&1
$DIS_CMD $THIS_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.this 2>&1 $DIS_CMD $THIS_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.this 2>&1
LANG=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff LC_ALL=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff
if [ -s $WORK_FILE_BASE.dis.diff ]; then if [ -s $WORK_FILE_BASE.dis.diff ]; then
DIS_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.dis.diff | awk '{print $5}') DIS_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.dis.diff | awk '{print $5}')

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -200,13 +200,8 @@ $(JPRT_ARCHIVE_BUNDLE): bundles
$(RM) $@ $(RM) $@
$(CP) $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip $@ $(CP) $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip $@
ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_BITS),solaris-64) SRC_JDK_IMAGE_DIR := $(JDK_IMAGE_DIR)
SRC_JDK_IMAGE_DIR := $(JDK_OVERLAY_IMAGE_DIR) SRC_JRE_IMAGE_DIR := $(JRE_IMAGE_DIR)
SRC_JRE_IMAGE_DIR := $(JRE_OVERLAY_IMAGE_DIR)
else
SRC_JDK_IMAGE_DIR := $(JDK_IMAGE_DIR)
SRC_JRE_IMAGE_DIR := $(JRE_IMAGE_DIR)
endif
SRC_JDK_BUNDLE_DIR := $(JDK_BUNDLE_DIR) SRC_JDK_BUNDLE_DIR := $(JDK_BUNDLE_DIR)
SRC_JRE_BUNDLE_DIR := $(JRE_BUNDLE_DIR) SRC_JRE_BUNDLE_DIR := $(JRE_BUNDLE_DIR)
@ -215,10 +210,10 @@ bundles: all bundles-only
bundles-only: start-make bundles-only: start-make
@$(call TargetEnter) @$(call TargetEnter)
$(MKDIR) -p $(BUILD_OUTPUT)/bundles $(MKDIR) -p $(BUILD_OUTPUT)/bundles
$(CD) $(SRC_JDK_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip . $(CD) $(SRC_JDK_IMAGE_DIR) && $(ZIP) -y -q -r $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip .
$(CD) $(SRC_JRE_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/$(JRE_IMAGE_SUBDIR).zip . $(CD) $(SRC_JRE_IMAGE_DIR) && $(ZIP) -y -q -r $(BUILD_OUTPUT)/bundles/$(JRE_IMAGE_SUBDIR).zip .
if [ -d $(BUILD_OUTPUT)/install/bundles ] ; then \ if [ -d $(BUILD_OUTPUT)/install/bundles ] ; then \
$(CD) $(BUILD_OUTPUT)/install/bundles && $(ZIP) -q -r $(JPRT_ARCHIVE_INSTALL_BUNDLE) . ; \ $(CD) $(BUILD_OUTPUT)/install/bundles && $(ZIP) -y -q -r $(JPRT_ARCHIVE_INSTALL_BUNDLE) . ; \
fi fi
@$(call TargetExit) @$(call TargetExit)

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -68,10 +68,6 @@ default: jdk
all: images docs all: images docs
@$(call CheckIfMakeAtEnd) @$(call CheckIfMakeAtEnd)
ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_BITS),solaris-64)
all: overlay-images
endif
# Setup a rule for SPEC file that fails if executed. This check makes sure the configuration # Setup a rule for SPEC file that fails if executed. This check makes sure the configuration
# is up to date after changes to configure # is up to date after changes to configure
$(SPEC): $(wildcard $(SRC_ROOT)/common/autoconf/*) $(SPEC): $(wildcard $(SRC_ROOT)/common/autoconf/*)

View File

@ -230,3 +230,4 @@ d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104
2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106 2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106
23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107 23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107
a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108 a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108
428428cf5e06163322144cfb5367e1faa86acf20 jdk8-b109

View File

@ -379,3 +379,5 @@ aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106
a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50
85072013aad46050a362d10ab78e963121c8014c jdk8-b108 85072013aad46050a362d10ab78e963121c8014c jdk8-b108
566db1b0e6efca31f181456e54c8911d0192410d hs25-b51 566db1b0e6efca31f181456e54c8911d0192410d hs25-b51
c81dd5393a5e333df7cb1f6621f5897ada6522b5 jdk8-b109
58043478c26d4e8bf48700acea5f97aba8b417d4 hs25-b52

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -698,29 +698,58 @@ err:
// read segments of a shared object // read segments of a shared object
static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) { static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
int i = 0; int i = 0;
ELF_PHDR* phbuf; ELF_PHDR* phbuf;
ELF_PHDR* lib_php = NULL; ELF_PHDR* lib_php = NULL;
if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) int page_size=sysconf(_SC_PAGE_SIZE);
return false;
// we want to process only PT_LOAD segments that are not writable. if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
// i.e., text segments. The read/write/exec (data) segments would return false;
// have been already added from core file segments. }
for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) { // we want to process only PT_LOAD segments that are not writable.
if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL) // i.e., text segments. The read/write/exec (data) segments would
goto err; // have been already added from core file segments.
for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
map_info *existing_map = core_lookup(ph, target_vaddr);
if (existing_map == NULL){
if (add_map_info(ph, lib_fd, lib_php->p_offset,
target_vaddr, lib_php->p_filesz) == NULL) {
goto err;
}
} else {
if ((existing_map->memsz != page_size) &&
(existing_map->fd != lib_fd) &&
(existing_map->memsz != lib_php->p_filesz)){
print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)",
target_vaddr, lib_php->p_filesz, lib_php->p_flags);
goto err;
}
/* replace PT_LOAD segment with library segment */
print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
existing_map->memsz, lib_php->p_filesz);
existing_map->fd = lib_fd;
existing_map->offset = lib_php->p_offset;
existing_map->memsz = lib_php->p_filesz;
} }
lib_php++; }
}
free(phbuf); lib_php++;
return true; }
free(phbuf);
return true;
err: err:
free(phbuf); free(phbuf);
return false; return false;
} }
// process segments from interpreter (ld.so or ld-linux.so) // process segments from interpreter (ld.so or ld-linux.so)

View File

@ -88,7 +88,7 @@ ifeq ($(INCLUDE_ALL_GCS), false)
g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \ g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \
g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp \ g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp \
g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \ g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \
heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \ g1BiasedArray.cpp heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \
ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp \ ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp \
adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \ adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \
cardTableExtension.cpp gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp \ cardTableExtension.cpp gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp \

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25 HS_MAJOR_VER=25
HS_MINOR_VER=0 HS_MINOR_VER=0
HS_BUILD_NUMBER=51 HS_BUILD_NUMBER=52
JDK_MAJOR_VER=1 JDK_MAJOR_VER=1
JDK_MINOR_VER=8 JDK_MINOR_VER=8

View File

@ -52,6 +52,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, oopDesc* receiver,
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
const int sparc_code_length = VtableStub::pd_code_size_limit(true); const int sparc_code_length = VtableStub::pd_code_size_limit(true);
VtableStub* s = new(sparc_code_length) VtableStub(true, vtable_index); VtableStub* s = new(sparc_code_length) VtableStub(true, vtable_index);
// Can be NULL if there is no free space in the code cache.
if (s == NULL) {
return NULL;
}
ResourceMark rm; ResourceMark rm;
CodeBuffer cb(s->entry_point(), sparc_code_length); CodeBuffer cb(s->entry_point(), sparc_code_length);
MacroAssembler* masm = new MacroAssembler(&cb); MacroAssembler* masm = new MacroAssembler(&cb);
@ -125,6 +130,11 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
VtableStub* VtableStubs::create_itable_stub(int itable_index) { VtableStub* VtableStubs::create_itable_stub(int itable_index) {
const int sparc_code_length = VtableStub::pd_code_size_limit(false); const int sparc_code_length = VtableStub::pd_code_size_limit(false);
VtableStub* s = new(sparc_code_length) VtableStub(false, itable_index); VtableStub* s = new(sparc_code_length) VtableStub(false, itable_index);
// Can be NULL if there is no free space in the code cache.
if (s == NULL) {
return NULL;
}
ResourceMark rm; ResourceMark rm;
CodeBuffer cb(s->entry_point(), sparc_code_length); CodeBuffer cb(s->entry_point(), sparc_code_length);
MacroAssembler* masm = new MacroAssembler(&cb); MacroAssembler* masm = new MacroAssembler(&cb);

View File

@ -58,6 +58,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
const int i486_code_length = VtableStub::pd_code_size_limit(true); const int i486_code_length = VtableStub::pd_code_size_limit(true);
VtableStub* s = new(i486_code_length) VtableStub(true, vtable_index); VtableStub* s = new(i486_code_length) VtableStub(true, vtable_index);
// Can be NULL if there is no free space in the code cache.
if (s == NULL) {
return NULL;
}
ResourceMark rm; ResourceMark rm;
CodeBuffer cb(s->entry_point(), i486_code_length); CodeBuffer cb(s->entry_point(), i486_code_length);
MacroAssembler* masm = new MacroAssembler(&cb); MacroAssembler* masm = new MacroAssembler(&cb);
@ -132,6 +137,11 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
// add code here, bump the code stub size returned by pd_code_size_limit! // add code here, bump the code stub size returned by pd_code_size_limit!
const int i486_code_length = VtableStub::pd_code_size_limit(false); const int i486_code_length = VtableStub::pd_code_size_limit(false);
VtableStub* s = new(i486_code_length) VtableStub(false, itable_index); VtableStub* s = new(i486_code_length) VtableStub(false, itable_index);
// Can be NULL if there is no free space in the code cache.
if (s == NULL) {
return NULL;
}
ResourceMark rm; ResourceMark rm;
CodeBuffer cb(s->entry_point(), i486_code_length); CodeBuffer cb(s->entry_point(), i486_code_length);
MacroAssembler* masm = new MacroAssembler(&cb); MacroAssembler* masm = new MacroAssembler(&cb);

View File

@ -49,6 +49,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread,
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
const int amd64_code_length = VtableStub::pd_code_size_limit(true); const int amd64_code_length = VtableStub::pd_code_size_limit(true);
VtableStub* s = new(amd64_code_length) VtableStub(true, vtable_index); VtableStub* s = new(amd64_code_length) VtableStub(true, vtable_index);
// Can be NULL if there is no free space in the code cache.
if (s == NULL) {
return NULL;
}
ResourceMark rm; ResourceMark rm;
CodeBuffer cb(s->entry_point(), amd64_code_length); CodeBuffer cb(s->entry_point(), amd64_code_length);
MacroAssembler* masm = new MacroAssembler(&cb); MacroAssembler* masm = new MacroAssembler(&cb);
@ -126,6 +131,11 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
// returned by pd_code_size_limit! // returned by pd_code_size_limit!
const int amd64_code_length = VtableStub::pd_code_size_limit(false); const int amd64_code_length = VtableStub::pd_code_size_limit(false);
VtableStub* s = new(amd64_code_length) VtableStub(false, itable_index); VtableStub* s = new(amd64_code_length) VtableStub(false, itable_index);
// Can be NULL if there is no free space in the code cache.
if (s == NULL) {
return NULL;
}
ResourceMark rm; ResourceMark rm;
CodeBuffer cb(s->entry_point(), amd64_code_length); CodeBuffer cb(s->entry_point(), amd64_code_length);
MacroAssembler* masm = new MacroAssembler(&cb); MacroAssembler* masm = new MacroAssembler(&cb);

View File

@ -4219,7 +4219,9 @@ void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool succes
} }
} }
if (!PrintInlining) return; if (!PrintInlining && !compilation()->method()->has_option("PrintInlining")) {
return;
}
CompileTask::print_inlining(callee, scope()->level(), bci(), msg); CompileTask::print_inlining(callee, scope()->level(), bci(), msg);
if (success && CIPrintMethodCodes) { if (success && CIPrintMethodCodes) {
callee->print_codes(); callee->print_codes();

View File

@ -438,6 +438,29 @@ bool java_lang_String::equals(oop java_string, jchar* chars, int len) {
return true; return true;
} }
bool java_lang_String::equals(oop str1, oop str2) {
assert(str1->klass() == SystemDictionary::String_klass(),
"must be java String");
assert(str2->klass() == SystemDictionary::String_klass(),
"must be java String");
typeArrayOop value1 = java_lang_String::value(str1);
int offset1 = java_lang_String::offset(str1);
int length1 = java_lang_String::length(str1);
typeArrayOop value2 = java_lang_String::value(str2);
int offset2 = java_lang_String::offset(str2);
int length2 = java_lang_String::length(str2);
if (length1 != length2) {
return false;
}
for (int i = 0; i < length1; i++) {
if (value1->char_at(i + offset1) != value2->char_at(i + offset2)) {
return false;
}
}
return true;
}
void java_lang_String::print(Handle java_string, outputStream* st) { void java_lang_String::print(Handle java_string, outputStream* st) {
oop obj = java_string(); oop obj = java_string();
assert(obj->klass() == SystemDictionary::String_klass(), "must be java_string"); assert(obj->klass() == SystemDictionary::String_klass(), "must be java_string");

View File

@ -182,6 +182,7 @@ class java_lang_String : AllStatic {
static unsigned int hash_string(oop java_string); static unsigned int hash_string(oop java_string);
static bool equals(oop java_string, jchar* chars, int len); static bool equals(oop java_string, jchar* chars, int len);
static bool equals(oop str1, oop str2);
// Conversion between '.' and '/' formats // Conversion between '.' and '/' formats
static Handle externalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '/', '.', THREAD); } static Handle externalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '/', '.', THREAD); }

View File

@ -341,7 +341,7 @@ Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
Symbol* SymbolTable::basic_add(int index_arg, u1 *name, int len, Symbol* SymbolTable::basic_add(int index_arg, u1 *name, int len,
unsigned int hashValue_arg, bool c_heap, TRAPS) { unsigned int hashValue_arg, bool c_heap, TRAPS) {
assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), assert(!Universe::heap()->is_in_reserved(name),
"proposed name of symbol must be stable"); "proposed name of symbol must be stable");
// Don't allow symbols to be created which cannot fit in a Symbol*. // Don't allow symbols to be created which cannot fit in a Symbol*.
@ -685,7 +685,7 @@ oop StringTable::intern(Handle string_or_null, jchar* name,
if (found_string != NULL) return found_string; if (found_string != NULL) return found_string;
debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), assert(!Universe::heap()->is_in_reserved(name),
"proposed name of symbol must be stable"); "proposed name of symbol must be stable");
Handle string; Handle string;
@ -807,6 +807,8 @@ void StringTable::possibly_parallel_oops_do(OopClosure* f) {
} }
} }
// This verification is part of Universe::verify() and needs to be quick.
// See StringTable::verify_and_compare() below for exhaustive verification.
void StringTable::verify() { void StringTable::verify() {
for (int i = 0; i < the_table()->table_size(); ++i) { for (int i = 0; i < the_table()->table_size(); ++i) {
HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i); HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
@ -825,6 +827,162 @@ void StringTable::dump(outputStream* st) {
the_table()->dump_table(st, "StringTable"); the_table()->dump_table(st, "StringTable");
} }
StringTable::VerifyRetTypes StringTable::compare_entries(
int bkt1, int e_cnt1,
HashtableEntry<oop, mtSymbol>* e_ptr1,
int bkt2, int e_cnt2,
HashtableEntry<oop, mtSymbol>* e_ptr2) {
// These entries are sanity checked by verify_and_compare_entries()
// before this function is called.
oop str1 = e_ptr1->literal();
oop str2 = e_ptr2->literal();
if (str1 == str2) {
tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") "
"in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]",
str1, bkt1, e_cnt1, bkt2, e_cnt2);
return _verify_fail_continue;
}
if (java_lang_String::equals(str1, str2)) {
tty->print_cr("ERROR: identical String values in entry @ "
"bucket[%d][%d] and entry @ bucket[%d][%d]",
bkt1, e_cnt1, bkt2, e_cnt2);
return _verify_fail_continue;
}
return _verify_pass;
}
StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt,
HashtableEntry<oop, mtSymbol>* e_ptr,
StringTable::VerifyMesgModes mesg_mode) {
VerifyRetTypes ret = _verify_pass; // be optimistic
oop str = e_ptr->literal();
if (str == NULL) {
if (mesg_mode == _verify_with_mesgs) {
tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt,
e_cnt);
}
// NULL oop means no more verifications are possible
return _verify_fail_done;
}
if (str->klass() != SystemDictionary::String_klass()) {
if (mesg_mode == _verify_with_mesgs) {
tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]",
bkt, e_cnt);
}
// not a String means no more verifications are possible
return _verify_fail_done;
}
unsigned int h = java_lang_String::hash_string(str);
if (e_ptr->hash() != h) {
if (mesg_mode == _verify_with_mesgs) {
tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], "
"bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h);
}
ret = _verify_fail_continue;
}
if (the_table()->hash_to_index(h) != bkt) {
if (mesg_mode == _verify_with_mesgs) {
tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], "
"str_hash=%d, hash_to_index=%d", bkt, e_cnt, h,
the_table()->hash_to_index(h));
}
ret = _verify_fail_continue;
}
return ret;
}
// See StringTable::verify() above for the quick verification that is
// part of Universe::verify(). This verification is exhaustive and
// reports on every issue that is found. StringTable::verify() only
// reports on the first issue that is found.
//
// StringTable::verify_entry() checks:
// - oop value != NULL (same as verify())
// - oop value is a String
// - hash(String) == hash in entry (same as verify())
// - index for hash == index of entry (same as verify())
//
// StringTable::compare_entries() checks:
// - oops are unique across all entries
// - String values are unique across all entries
//
int StringTable::verify_and_compare_entries() {
assert(StringTable_lock->is_locked(), "sanity check");
int fail_cnt = 0;
// first, verify all the entries individually:
for (int bkt = 0; bkt < the_table()->table_size(); bkt++) {
HashtableEntry<oop, mtSymbol>* e_ptr = the_table()->bucket(bkt);
for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) {
VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs);
if (ret != _verify_pass) {
fail_cnt++;
}
}
}
// Optimization: if the above check did not find any failures, then
// the comparison loop below does not need to call verify_entry()
// before calling compare_entries(). If there were failures, then we
// have to call verify_entry() to see if the entry can be passed to
// compare_entries() safely. When we call verify_entry() in the loop
// below, we do so quietly to void duplicate messages and we don't
// increment fail_cnt because the failures have already been counted.
bool need_entry_verify = (fail_cnt != 0);
// second, verify all entries relative to each other:
for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) {
HashtableEntry<oop, mtSymbol>* e_ptr1 = the_table()->bucket(bkt1);
for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) {
if (need_entry_verify) {
VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1,
_verify_quietly);
if (ret == _verify_fail_done) {
// cannot use the current entry to compare against other entries
continue;
}
}
for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) {
HashtableEntry<oop, mtSymbol>* e_ptr2 = the_table()->bucket(bkt2);
int e_cnt2;
for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) {
if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) {
// skip the entries up to and including the one that
// we're comparing against
continue;
}
if (need_entry_verify) {
VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2,
_verify_quietly);
if (ret == _verify_fail_done) {
// cannot compare against this entry
continue;
}
}
// compare two entries, report and count any failures:
if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2)
!= _verify_pass) {
fail_cnt++;
}
}
}
}
}
return fail_cnt;
}
// Create a new table and using alternate hash code, populate the new table // Create a new table and using alternate hash code, populate the new table
// with the existing strings. Set flag to use the alternate hash code afterwards. // with the existing strings. Set flag to use the alternate hash code afterwards.

View File

@ -311,6 +311,26 @@ public:
static void verify(); static void verify();
static void dump(outputStream* st); static void dump(outputStream* st);
enum VerifyMesgModes {
_verify_quietly = 0,
_verify_with_mesgs = 1
};
enum VerifyRetTypes {
_verify_pass = 0,
_verify_fail_continue = 1,
_verify_fail_done = 2
};
static VerifyRetTypes compare_entries(int bkt1, int e_cnt1,
HashtableEntry<oop, mtSymbol>* e_ptr1,
int bkt2, int e_cnt2,
HashtableEntry<oop, mtSymbol>* e_ptr2);
static VerifyRetTypes verify_entry(int bkt, int e_cnt,
HashtableEntry<oop, mtSymbol>* e_ptr,
VerifyMesgModes mesg_mode);
static int verify_and_compare_entries();
// Sharing // Sharing
static void copy_buckets(char** top, char*end) { static void copy_buckets(char** top, char*end) {
the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end); the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end);

View File

@ -160,7 +160,7 @@ address CompiledIC::stub_address() const {
// High-level access to an inline cache. Guaranteed to be MT-safe. // High-level access to an inline cache. Guaranteed to be MT-safe.
void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) {
assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "");
assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic");
assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?");
@ -170,8 +170,10 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod
assert(bytecode == Bytecodes::_invokeinterface, ""); assert(bytecode == Bytecodes::_invokeinterface, "");
int itable_index = call_info->itable_index(); int itable_index = call_info->itable_index();
entry = VtableStubs::find_itable_stub(itable_index); entry = VtableStubs::find_itable_stub(itable_index);
if (entry == false) {
return false;
}
#ifdef ASSERT #ifdef ASSERT
assert(entry != NULL, "entry not computed");
int index = call_info->resolved_method()->itable_index(); int index = call_info->resolved_method()->itable_index();
assert(index == itable_index, "CallInfo pre-computes this"); assert(index == itable_index, "CallInfo pre-computes this");
#endif //ASSERT #endif //ASSERT
@ -184,6 +186,9 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod
int vtable_index = call_info->vtable_index(); int vtable_index = call_info->vtable_index();
assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check");
entry = VtableStubs::find_vtable_stub(vtable_index); entry = VtableStubs::find_vtable_stub(vtable_index);
if (entry == NULL) {
return false;
}
InlineCacheBuffer::create_transition_stub(this, NULL, entry); InlineCacheBuffer::create_transition_stub(this, NULL, entry);
} }
@ -200,6 +205,7 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod
// race because the IC entry was complete when we safepointed so // race because the IC entry was complete when we safepointed so
// cleaning it immediately is harmless. // cleaning it immediately is harmless.
// assert(is_megamorphic(), "sanity check"); // assert(is_megamorphic(), "sanity check");
return true;
} }

View File

@ -226,7 +226,10 @@ class CompiledIC: public ResourceObj {
// //
void set_to_clean(); // Can only be called during a safepoint operation void set_to_clean(); // Can only be called during a safepoint operation
void set_to_monomorphic(CompiledICInfo& info); void set_to_monomorphic(CompiledICInfo& info);
void set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS);
// Returns true if successful and false otherwise. The call can fail if memory
// allocation in the code cache fails.
bool set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS);
static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass, static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass,
bool is_optimized, bool static_bound, CompiledICInfo& info, TRAPS); bool is_optimized, bool static_bound, CompiledICInfo& info, TRAPS);

View File

@ -46,12 +46,9 @@ address VtableStub::_chunk = NULL;
address VtableStub::_chunk_end = NULL; address VtableStub::_chunk_end = NULL;
VMReg VtableStub::_receiver_location = VMRegImpl::Bad(); VMReg VtableStub::_receiver_location = VMRegImpl::Bad();
static int num_vtable_chunks = 0;
void* VtableStub::operator new(size_t size, int code_size) throw() { void* VtableStub::operator new(size_t size, int code_size) throw() {
assert(size == sizeof(VtableStub), "mismatched size"); assert(size == sizeof(VtableStub), "mismatched size");
num_vtable_chunks++;
// compute real VtableStub size (rounded to nearest word) // compute real VtableStub size (rounded to nearest word)
const int real_size = round_to(code_size + sizeof(VtableStub), wordSize); const int real_size = round_to(code_size + sizeof(VtableStub), wordSize);
// malloc them in chunks to minimize header overhead // malloc them in chunks to minimize header overhead
@ -60,7 +57,7 @@ void* VtableStub::operator new(size_t size, int code_size) throw() {
const int bytes = chunk_factor * real_size + pd_code_alignment(); const int bytes = chunk_factor * real_size + pd_code_alignment();
BufferBlob* blob = BufferBlob::create("vtable chunks", bytes); BufferBlob* blob = BufferBlob::create("vtable chunks", bytes);
if (blob == NULL) { if (blob == NULL) {
vm_exit_out_of_memory(bytes, OOM_MALLOC_ERROR, "CodeCache: no room for vtable chunks"); return NULL;
} }
_chunk = blob->content_begin(); _chunk = blob->content_begin();
_chunk_end = _chunk + bytes; _chunk_end = _chunk + bytes;
@ -121,6 +118,12 @@ address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) {
} else { } else {
s = create_itable_stub(vtable_index); s = create_itable_stub(vtable_index);
} }
// Creation of vtable or itable can fail if there is not enough free space in the code cache.
if (s == NULL) {
return NULL;
}
enter(is_vtable_stub, vtable_index, s); enter(is_vtable_stub, vtable_index, s);
if (PrintAdapterHandlers) { if (PrintAdapterHandlers) {
tty->print_cr("Decoding VtableStub %s[%d]@%d", tty->print_cr("Decoding VtableStub %s[%d]@%d",

View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "gc_implementation/g1/g1BiasedArray.hpp"
#ifndef PRODUCT
void G1BiasedMappedArrayBase::verify_index(idx_t index) const {
guarantee(_base != NULL, "Array not initialized");
guarantee(index < length(), err_msg("Index out of bounds index: "SIZE_FORMAT" length: "SIZE_FORMAT, index, length()));
}
void G1BiasedMappedArrayBase::verify_biased_index(idx_t biased_index) const {
guarantee(_biased_base != NULL, "Array not initialized");
guarantee(biased_index >= bias() && biased_index < (bias() + length()),
err_msg("Biased index out of bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length()));
}
void G1BiasedMappedArrayBase::verify_biased_index_inclusive_end(idx_t biased_index) const {
guarantee(_biased_base != NULL, "Array not initialized");
guarantee(biased_index >= bias() && biased_index <= (bias() + length()),
err_msg("Biased index out of inclusive bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length()));
}
class TestMappedArray : public G1BiasedMappedArray<int> {
protected:
virtual int default_value() const { return 0xBAADBABE; }
public:
static void test_biasedarray() {
const size_t REGION_SIZE_IN_WORDS = 512;
const size_t NUM_REGIONS = 20;
HeapWord* fake_heap = (HeapWord*)LP64_ONLY(0xBAAA00000) NOT_LP64(0xBA000000); // Any value that is non-zero
TestMappedArray array;
array.initialize(fake_heap, fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS,
REGION_SIZE_IN_WORDS * HeapWordSize);
// Check address calculation (bounds)
assert(array.bottom_address_mapped() == fake_heap,
err_msg("bottom mapped address should be "PTR_FORMAT", but is "PTR_FORMAT, fake_heap, array.bottom_address_mapped()));
assert(array.end_address_mapped() == (fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS), "must be");
int* bottom = array.address_mapped_to(fake_heap);
assert((void*)bottom == (void*) array.base(), "must be");
int* end = array.address_mapped_to(fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS);
assert((void*)end == (void*)(array.base() + array.length()), "must be");
// The entire array should contain default value elements
for (int* current = bottom; current < end; current++) {
assert(*current == array.default_value(), "must be");
}
// Test setting values in the table
HeapWord* region_start_address = fake_heap + REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2);
HeapWord* region_end_address = fake_heap + (REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2) + REGION_SIZE_IN_WORDS - 1);
// Set/get by address tests: invert some value; first retrieve one
int actual_value = array.get_by_index(NUM_REGIONS / 2);
array.set_by_index(NUM_REGIONS / 2, ~actual_value);
// Get the same value by address, should correspond to the start of the "region"
int value = array.get_by_address(region_start_address);
assert(value == ~actual_value, "must be");
// Get the same value by address, at one HeapWord before the start
value = array.get_by_address(region_start_address - 1);
assert(value == array.default_value(), "must be");
// Get the same value by address, at the end of the "region"
value = array.get_by_address(region_end_address);
assert(value == ~actual_value, "must be");
// Make sure the next value maps to another index
value = array.get_by_address(region_end_address + 1);
assert(value == array.default_value(), "must be");
// Reset the value in the array
array.set_by_address(region_start_address + (region_end_address - region_start_address) / 2, actual_value);
// The entire array should have the default value again
for (int* current = bottom; current < end; current++) {
assert(*current == array.default_value(), "must be");
}
// Set/get by index tests: invert some value
idx_t index = NUM_REGIONS / 2;
actual_value = array.get_by_index(index);
array.set_by_index(index, ~actual_value);
value = array.get_by_index(index);
assert(value == ~actual_value, "must be");
value = array.get_by_index(index - 1);
assert(value == array.default_value(), "must be");
value = array.get_by_index(index + 1);
assert(value == array.default_value(), "must be");
array.set_by_index(0, 0);
value = array.get_by_index(0);
assert(value == 0, "must be");
array.set_by_index(array.length() - 1, 0);
value = array.get_by_index(array.length() - 1);
assert(value == 0, "must be");
array.set_by_index(index, 0);
// The array should have three zeros, and default values otherwise
size_t num_zeros = 0;
for (int* current = bottom; current < end; current++) {
assert(*current == array.default_value() || *current == 0, "must be");
if (*current == 0) {
num_zeros++;
}
}
assert(num_zeros == 3, "must be");
}
};
void TestG1BiasedArray_test() {
TestMappedArray::test_biasedarray();
}
#endif

View File

@ -0,0 +1,181 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP
#define SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP
#include "utilities/debug.hpp"
#include "memory/allocation.inline.hpp"
// Implements the common base functionality for arrays that contain provisions
// for accessing its elements using a biased index.
// The element type is defined by the instantiating the template.
class G1BiasedMappedArrayBase VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
public:
typedef size_t idx_t;
protected:
address _base; // the real base address
size_t _length; // the length of the array
address _biased_base; // base address biased by "bias" elements
size_t _bias; // the bias, i.e. the offset biased_base is located to the right in elements
uint _shift_by; // the amount of bits to shift right when mapping to an index of the array.
protected:
G1BiasedMappedArrayBase() : _base(NULL), _length(0), _biased_base(NULL),
_bias(0), _shift_by(0) { }
// Allocate a new array, generic version.
static address create_new_base_array(size_t length, size_t elem_size) {
assert(length > 0, "just checking");
assert(elem_size > 0, "just checking");
return NEW_C_HEAP_ARRAY(u_char, length * elem_size, mtGC);
}
// Initialize the members of this class. The biased start address of this array
// is the bias (in elements) multiplied by the element size.
void initialize_base(address base, size_t length, size_t bias, size_t elem_size, uint shift_by) {
assert(base != NULL, "just checking");
assert(length > 0, "just checking");
assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by %zd, larger than word size?", shift_by));
_base = base;
_length = length;
_biased_base = base - (bias * elem_size);
_bias = bias;
_shift_by = shift_by;
}
// Allocate and initialize this array to cover the heap addresses in the range
// of [bottom, end).
void initialize(HeapWord* bottom, HeapWord* end, size_t target_elem_size_in_bytes, size_t mapping_granularity_in_bytes) {
assert(mapping_granularity_in_bytes > 0, "just checking");
assert(is_power_of_2(mapping_granularity_in_bytes),
err_msg("mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes));
assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0,
err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT,
mapping_granularity_in_bytes, bottom));
assert((uintptr_t)end % mapping_granularity_in_bytes == 0,
err_msg("end mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT,
mapping_granularity_in_bytes, end));
size_t num_target_elems = (end - bottom) / (mapping_granularity_in_bytes / HeapWordSize);
idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes;
address base = create_new_base_array(num_target_elems, target_elem_size_in_bytes);
initialize_base(base, num_target_elems, bias, target_elem_size_in_bytes, log2_intptr(mapping_granularity_in_bytes));
}
size_t bias() const { return _bias; }
uint shift_by() const { return _shift_by; }
void verify_index(idx_t index) const PRODUCT_RETURN;
void verify_biased_index(idx_t biased_index) const PRODUCT_RETURN;
void verify_biased_index_inclusive_end(idx_t biased_index) const PRODUCT_RETURN;
public:
// Return the length of the array in elements.
size_t length() const { return _length; }
};
// Array that provides biased access and mapping from (valid) addresses in the
// heap into this array.
template<class T>
class G1BiasedMappedArray : public G1BiasedMappedArrayBase {
public:
typedef G1BiasedMappedArrayBase::idx_t idx_t;
T* base() const { return (T*)G1BiasedMappedArrayBase::_base; }
// Return the element of the given array at the given index. Assume
// the index is valid. This is a convenience method that does sanity
// checking on the index.
T get_by_index(idx_t index) const {
verify_index(index);
return this->base()[index];
}
// Set the element of the given array at the given index to the
// given value. Assume the index is valid. This is a convenience
// method that does sanity checking on the index.
void set_by_index(idx_t index, T value) {
verify_index(index);
this->base()[index] = value;
}
// The raw biased base pointer.
T* biased_base() const { return (T*)G1BiasedMappedArrayBase::_biased_base; }
// Return the element of the given array that covers the given word in the
// heap. Assumes the index is valid.
T get_by_address(HeapWord* value) const {
idx_t biased_index = ((uintptr_t)value) >> this->shift_by();
this->verify_biased_index(biased_index);
return biased_base()[biased_index];
}
// Set the value of the array entry that corresponds to the given array.
void set_by_address(HeapWord * address, T value) {
idx_t biased_index = ((uintptr_t)address) >> this->shift_by();
this->verify_biased_index(biased_index);
biased_base()[biased_index] = value;
}
protected:
// Returns the address of the element the given address maps to
T* address_mapped_to(HeapWord* address) {
idx_t biased_index = ((uintptr_t)address) >> this->shift_by();
this->verify_biased_index_inclusive_end(biased_index);
return biased_base() + biased_index;
}
public:
// Return the smallest address (inclusive) in the heap that this array covers.
HeapWord* bottom_address_mapped() const {
return (HeapWord*) ((uintptr_t)this->bias() << this->shift_by());
}
// Return the highest address (exclusive) in the heap that this array covers.
HeapWord* end_address_mapped() const {
return (HeapWord*) ((uintptr_t)(this->bias() + this->length()) << this->shift_by());
}
protected:
virtual T default_value() const = 0;
// Set all elements of the given array to the given value.
void clear() {
T value = default_value();
for (idx_t i = 0; i < length(); i++) {
set_by_index(i, value);
}
}
public:
G1BiasedMappedArray() {}
// Allocate and initialize this array to cover the heap addresses in the range
// of [bottom, end).
void initialize(HeapWord* bottom, HeapWord* end, size_t mapping_granularity) {
G1BiasedMappedArrayBase::initialize(bottom, end, sizeof(T), mapping_granularity);
this->clear();
}
};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP

View File

@ -2069,8 +2069,10 @@ jint G1CollectedHeap::initialize() {
_g1_storage.initialize(g1_rs, 0); _g1_storage.initialize(g1_rs, 0);
_g1_committed = MemRegion((HeapWord*)_g1_storage.low(), (size_t) 0); _g1_committed = MemRegion((HeapWord*)_g1_storage.low(), (size_t) 0);
_hrs.initialize((HeapWord*) _g1_reserved.start(), _hrs.initialize((HeapWord*) _g1_reserved.start(),
(HeapWord*) _g1_reserved.end(), (HeapWord*) _g1_reserved.end());
_expansion_regions); assert(_hrs.max_length() == _expansion_regions,
err_msg("max length: %u expansion regions: %u",
_hrs.max_length(), _expansion_regions));
// Do later initialization work for concurrent refinement. // Do later initialization work for concurrent refinement.
_cg1r->init(); _cg1r->init();

View File

@ -71,27 +71,16 @@ uint HeapRegionSeq::find_contiguous_from(uint from, uint num) {
// Public // Public
void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end, void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end) {
uint max_length) {
assert((uintptr_t) bottom % HeapRegion::GrainBytes == 0, assert((uintptr_t) bottom % HeapRegion::GrainBytes == 0,
"bottom should be heap region aligned"); "bottom should be heap region aligned");
assert((uintptr_t) end % HeapRegion::GrainBytes == 0, assert((uintptr_t) end % HeapRegion::GrainBytes == 0,
"end should be heap region aligned"); "end should be heap region aligned");
_length = 0;
_heap_bottom = bottom;
_heap_end = end;
_region_shift = HeapRegion::LogOfHRGrainBytes;
_next_search_index = 0; _next_search_index = 0;
_allocated_length = 0; _allocated_length = 0;
_max_length = max_length;
_regions = NEW_C_HEAP_ARRAY(HeapRegion*, max_length, mtGC); _regions.initialize(bottom, end, HeapRegion::GrainBytes);
memset(_regions, 0, (size_t) max_length * sizeof(HeapRegion*));
_regions_biased = _regions - ((uintx) bottom >> _region_shift);
assert(&_regions[0] == &_regions_biased[addr_to_index_biased(bottom)],
"bottom should be included in the region with index 0");
} }
MemRegion HeapRegionSeq::expand_by(HeapWord* old_end, MemRegion HeapRegionSeq::expand_by(HeapWord* old_end,
@ -101,15 +90,15 @@ MemRegion HeapRegionSeq::expand_by(HeapWord* old_end,
G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectedHeap* g1h = G1CollectedHeap::heap();
HeapWord* next_bottom = old_end; HeapWord* next_bottom = old_end;
assert(_heap_bottom <= next_bottom, "invariant"); assert(heap_bottom() <= next_bottom, "invariant");
while (next_bottom < new_end) { while (next_bottom < new_end) {
assert(next_bottom < _heap_end, "invariant"); assert(next_bottom < heap_end(), "invariant");
uint index = length(); uint index = length();
assert(index < _max_length, "otherwise we cannot expand further"); assert(index < max_length(), "otherwise we cannot expand further");
if (index == 0) { if (index == 0) {
// We have not allocated any regions so far // We have not allocated any regions so far
assert(next_bottom == _heap_bottom, "invariant"); assert(next_bottom == heap_bottom(), "invariant");
} else { } else {
// next_bottom should match the end of the last/previous region // next_bottom should match the end of the last/previous region
assert(next_bottom == at(index - 1)->end(), "invariant"); assert(next_bottom == at(index - 1)->end(), "invariant");
@ -122,8 +111,8 @@ MemRegion HeapRegionSeq::expand_by(HeapWord* old_end,
// allocation failed, we bail out and return what we have done so far // allocation failed, we bail out and return what we have done so far
return MemRegion(old_end, next_bottom); return MemRegion(old_end, next_bottom);
} }
assert(_regions[index] == NULL, "invariant"); assert(_regions.get_by_index(index) == NULL, "invariant");
_regions[index] = new_hr; _regions.set_by_index(index, new_hr);
increment_allocated_length(); increment_allocated_length();
} }
// Have to increment the length first, otherwise we will get an // Have to increment the length first, otherwise we will get an
@ -228,26 +217,26 @@ uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) {
#ifndef PRODUCT #ifndef PRODUCT
void HeapRegionSeq::verify_optional() { void HeapRegionSeq::verify_optional() {
guarantee(_length <= _allocated_length, guarantee(length() <= _allocated_length,
err_msg("invariant: _length: %u _allocated_length: %u", err_msg("invariant: _length: %u _allocated_length: %u",
_length, _allocated_length)); length(), _allocated_length));
guarantee(_allocated_length <= _max_length, guarantee(_allocated_length <= max_length(),
err_msg("invariant: _allocated_length: %u _max_length: %u", err_msg("invariant: _allocated_length: %u _max_length: %u",
_allocated_length, _max_length)); _allocated_length, max_length()));
guarantee(_next_search_index <= _length, guarantee(_next_search_index <= length(),
err_msg("invariant: _next_search_index: %u _length: %u", err_msg("invariant: _next_search_index: %u _length: %u",
_next_search_index, _length)); _next_search_index, length()));
HeapWord* prev_end = _heap_bottom; HeapWord* prev_end = heap_bottom();
for (uint i = 0; i < _allocated_length; i += 1) { for (uint i = 0; i < _allocated_length; i += 1) {
HeapRegion* hr = _regions[i]; HeapRegion* hr = _regions.get_by_index(i);
guarantee(hr != NULL, err_msg("invariant: i: %u", i)); guarantee(hr != NULL, err_msg("invariant: i: %u", i));
guarantee(hr->bottom() == prev_end, guarantee(hr->bottom() == prev_end,
err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
i, HR_FORMAT_PARAMS(hr), prev_end)); i, HR_FORMAT_PARAMS(hr), prev_end));
guarantee(hr->hrs_index() == i, guarantee(hr->hrs_index() == i,
err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index())); err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index()));
if (i < _length) { if (i < length()) {
// Asserts will fire if i is >= _length // Asserts will fire if i is >= _length
HeapWord* addr = hr->bottom(); HeapWord* addr = hr->bottom();
guarantee(addr_to_region(addr) == hr, "sanity"); guarantee(addr_to_region(addr) == hr, "sanity");
@ -265,8 +254,8 @@ void HeapRegionSeq::verify_optional() {
prev_end = hr->end(); prev_end = hr->end();
} }
} }
for (uint i = _allocated_length; i < _max_length; i += 1) { for (uint i = _allocated_length; i < max_length(); i += 1) {
guarantee(_regions[i] == NULL, err_msg("invariant i: %u", i)); guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i));
} }
} }
#endif // PRODUCT #endif // PRODUCT

View File

@ -25,10 +25,17 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
#include "gc_implementation/g1/g1BiasedArray.hpp"
class HeapRegion; class HeapRegion;
class HeapRegionClosure; class HeapRegionClosure;
class FreeRegionList; class FreeRegionList;
class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
protected:
virtual HeapRegion* default_value() const { return NULL; }
};
// This class keeps track of the region metadata (i.e., HeapRegion // This class keeps track of the region metadata (i.e., HeapRegion
// instances). They are kept in the _regions array in address // instances). They are kept in the _regions array in address
// order. A region's index in the array corresponds to its index in // order. A region's index in the array corresponds to its index in
@ -44,35 +51,21 @@ class FreeRegionList;
// //
// We keep track of three lengths: // We keep track of three lengths:
// //
// * _length (returned by length()) is the number of currently // * _committed_length (returned by length()) is the number of currently
// committed regions. // committed regions.
// * _allocated_length (not exposed outside this class) is the // * _allocated_length (not exposed outside this class) is the
// number of regions for which we have HeapRegions. // number of regions for which we have HeapRegions.
// * _max_length (returned by max_length()) is the maximum number of // * max_length() returns the maximum number of regions the heap can have.
// regions the heap can have.
// //
// and maintain that: _length <= _allocated_length <= _max_length // and maintain that: _committed_length <= _allocated_length <= max_length()
class HeapRegionSeq: public CHeapObj<mtGC> { class HeapRegionSeq: public CHeapObj<mtGC> {
friend class VMStructs; friend class VMStructs;
// The array that holds the HeapRegions. G1HeapRegionTable _regions;
HeapRegion** _regions;
// Version of _regions biased to address 0
HeapRegion** _regions_biased;
// The number of regions committed in the heap. // The number of regions committed in the heap.
uint _length; uint _committed_length;
// The address of the first reserved word in the heap.
HeapWord* _heap_bottom;
// The address of the last reserved word in the heap - 1.
HeapWord* _heap_end;
// The log of the region byte size.
uint _region_shift;
// A hint for which index to start searching from for humongous // A hint for which index to start searching from for humongous
// allocations. // allocations.
@ -81,37 +74,33 @@ class HeapRegionSeq: public CHeapObj<mtGC> {
// The number of regions for which we have allocated HeapRegions for. // The number of regions for which we have allocated HeapRegions for.
uint _allocated_length; uint _allocated_length;
// The maximum number of regions in the heap.
uint _max_length;
// Find a contiguous set of empty regions of length num, starting // Find a contiguous set of empty regions of length num, starting
// from the given index. // from the given index.
uint find_contiguous_from(uint from, uint num); uint find_contiguous_from(uint from, uint num);
// Map a heap address to a biased region index. Assume that the
// address is valid.
inline uintx addr_to_index_biased(HeapWord* addr) const;
void increment_allocated_length() { void increment_allocated_length() {
assert(_allocated_length < _max_length, "pre-condition"); assert(_allocated_length < max_length(), "pre-condition");
_allocated_length++; _allocated_length++;
} }
void increment_length() { void increment_length() {
assert(_length < _max_length, "pre-condition"); assert(length() < max_length(), "pre-condition");
_length++; _committed_length++;
} }
void decrement_length() { void decrement_length() {
assert(_length > 0, "pre-condition"); assert(length() > 0, "pre-condition");
_length--; _committed_length--;
} }
HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
HeapWord* heap_end() const {return _regions.end_address_mapped(); }
public: public:
// Empty contructor, we'll initialize it with the initialize() method. // Empty contructor, we'll initialize it with the initialize() method.
HeapRegionSeq() { } HeapRegionSeq() : _regions(), _committed_length(0), _next_search_index(0), _allocated_length(0) { }
void initialize(HeapWord* bottom, HeapWord* end, uint max_length); void initialize(HeapWord* bottom, HeapWord* end);
// Return the HeapRegion at the given index. Assume that the index // Return the HeapRegion at the given index. Assume that the index
// is valid. // is valid.
@ -126,10 +115,10 @@ class HeapRegionSeq: public CHeapObj<mtGC> {
inline HeapRegion* addr_to_region_unsafe(HeapWord* addr) const; inline HeapRegion* addr_to_region_unsafe(HeapWord* addr) const;
// Return the number of regions that have been committed in the heap. // Return the number of regions that have been committed in the heap.
uint length() const { return _length; } uint length() const { return _committed_length; }
// Return the maximum number of regions in the heap. // Return the maximum number of regions in the heap.
uint max_length() const { return _max_length; } uint max_length() const { return (uint)_regions.length(); }
// Expand the sequence to reflect that the heap has grown from // Expand the sequence to reflect that the heap has grown from
// old_end to new_end. Either create new HeapRegions, or re-use // old_end to new_end. Either create new HeapRegions, or re-use

View File

@ -28,28 +28,16 @@
#include "gc_implementation/g1/heapRegion.hpp" #include "gc_implementation/g1/heapRegion.hpp"
#include "gc_implementation/g1/heapRegionSeq.hpp" #include "gc_implementation/g1/heapRegionSeq.hpp"
inline uintx HeapRegionSeq::addr_to_index_biased(HeapWord* addr) const {
assert(_heap_bottom <= addr && addr < _heap_end,
err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT" end: "PTR_FORMAT,
addr, _heap_bottom, _heap_end));
uintx index = (uintx) addr >> _region_shift;
return index;
}
inline HeapRegion* HeapRegionSeq::addr_to_region_unsafe(HeapWord* addr) const { inline HeapRegion* HeapRegionSeq::addr_to_region_unsafe(HeapWord* addr) const {
assert(_heap_bottom <= addr && addr < _heap_end, HeapRegion* hr = _regions.get_by_address(addr);
err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT" end: "PTR_FORMAT,
addr, _heap_bottom, _heap_end));
uintx index_biased = addr_to_index_biased(addr);
HeapRegion* hr = _regions_biased[index_biased];
assert(hr != NULL, "invariant"); assert(hr != NULL, "invariant");
return hr; return hr;
} }
inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const {
if (addr != NULL && addr < _heap_end) { if (addr != NULL && addr < heap_end()) {
assert(addr >= _heap_bottom, assert(addr >= heap_bottom(),
err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, _heap_bottom)); err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, heap_bottom()));
return addr_to_region_unsafe(addr); return addr_to_region_unsafe(addr);
} }
return NULL; return NULL;
@ -57,7 +45,7 @@ inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const {
inline HeapRegion* HeapRegionSeq::at(uint index) const { inline HeapRegion* HeapRegionSeq::at(uint index) const {
assert(index < length(), "pre-condition"); assert(index < length(), "pre-condition");
HeapRegion* hr = _regions[index]; HeapRegion* hr = _regions.get_by_index(index);
assert(hr != NULL, "sanity"); assert(hr != NULL, "sanity");
assert(hr->hrs_index() == index, "sanity"); assert(hr->hrs_index() == index, "sanity");
return hr; return hr;

View File

@ -34,8 +34,14 @@
static_field(HeapRegion, GrainBytes, size_t) \ static_field(HeapRegion, GrainBytes, size_t) \
static_field(HeapRegion, LogOfHRGrainBytes, int) \ static_field(HeapRegion, LogOfHRGrainBytes, int) \
\ \
nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \ nonstatic_field(G1HeapRegionTable, _base, address) \
nonstatic_field(HeapRegionSeq, _length, uint) \ nonstatic_field(G1HeapRegionTable, _length, size_t) \
nonstatic_field(G1HeapRegionTable, _biased_base, address) \
nonstatic_field(G1HeapRegionTable, _bias, size_t) \
nonstatic_field(G1HeapRegionTable, _shift_by, uint) \
\
nonstatic_field(HeapRegionSeq, _regions, G1HeapRegionTable) \
nonstatic_field(HeapRegionSeq, _committed_length, uint) \
\ \
nonstatic_field(G1CollectedHeap, _hrs, HeapRegionSeq) \ nonstatic_field(G1CollectedHeap, _hrs, HeapRegionSeq) \
nonstatic_field(G1CollectedHeap, _g1_committed, MemRegion) \ nonstatic_field(G1CollectedHeap, _g1_committed, MemRegion) \
@ -58,6 +64,8 @@
#define VM_TYPES_G1(declare_type, declare_toplevel_type) \ #define VM_TYPES_G1(declare_type, declare_toplevel_type) \
\ \
declare_toplevel_type(G1HeapRegionTable) \
\
declare_type(G1CollectedHeap, SharedHeap) \ declare_type(G1CollectedHeap, SharedHeap) \
\ \
declare_type(HeapRegion, ContiguousSpace) \ declare_type(HeapRegion, ContiguousSpace) \

View File

@ -122,7 +122,7 @@ void GC_locker::jni_unlock(JavaThread* thread) {
// strictly needed. It's added here to make it clear that // strictly needed. It's added here to make it clear that
// the GC will NOT be performed if any other caller // the GC will NOT be performed if any other caller
// of GC_locker::lock() still needs GC locked. // of GC_locker::lock() still needs GC locked.
if (!is_active()) { if (!is_active_internal()) {
_doing_gc = true; _doing_gc = true;
{ {
// Must give up the lock while at a safepoint // Must give up the lock while at a safepoint

View File

@ -88,7 +88,7 @@ class GC_locker: public AllStatic {
public: public:
// Accessors // Accessors
static bool is_active() { static bool is_active() {
assert(_needs_gc || SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
return is_active_internal(); return is_active_internal();
} }
static bool needs_gc() { return _needs_gc; } static bool needs_gc() { return _needs_gc; }

View File

@ -23,6 +23,7 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc_interface/collectedHeap.hpp" #include "gc_interface/collectedHeap.hpp"
#include "memory/allocation.hpp"
#include "memory/binaryTreeDictionary.hpp" #include "memory/binaryTreeDictionary.hpp"
#include "memory/freeList.hpp" #include "memory/freeList.hpp"
#include "memory/collectorPolicy.hpp" #include "memory/collectorPolicy.hpp"
@ -111,7 +112,7 @@ typedef class FreeList<Metachunk> ChunkList;
// Has three lists of free chunks, and a total size and // Has three lists of free chunks, and a total size and
// count that includes all three // count that includes all three
class ChunkManager VALUE_OBJ_CLASS_SPEC { class ChunkManager : public CHeapObj<mtInternal> {
// Free list of chunks of different sizes. // Free list of chunks of different sizes.
// SpecializedChunk // SpecializedChunk
@ -158,7 +159,12 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC {
public: public:
ChunkManager() : _free_chunks_total(0), _free_chunks_count(0) {} ChunkManager(size_t specialized_size, size_t small_size, size_t medium_size)
: _free_chunks_total(0), _free_chunks_count(0) {
_free_chunks[SpecializedIndex].set_size(specialized_size);
_free_chunks[SmallIndex].set_size(small_size);
_free_chunks[MediumIndex].set_size(medium_size);
}
// add or delete (return) a chunk to the global freelist. // add or delete (return) a chunk to the global freelist.
Metachunk* chunk_freelist_allocate(size_t word_size); Metachunk* chunk_freelist_allocate(size_t word_size);
@ -219,7 +225,7 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC {
void locked_print_free_chunks(outputStream* st); void locked_print_free_chunks(outputStream* st);
void locked_print_sum_free_chunks(outputStream* st); void locked_print_sum_free_chunks(outputStream* st);
void print_on(outputStream* st); void print_on(outputStream* st) const;
}; };
// Used to manage the free list of Metablocks (a block corresponds // Used to manage the free list of Metablocks (a block corresponds
@ -276,11 +282,6 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
// VirtualSpace // VirtualSpace
Metachunk* first_chunk() { return (Metachunk*) bottom(); } Metachunk* first_chunk() { return (Metachunk*) bottom(); }
void inc_container_count();
#ifdef ASSERT
uint container_count_slow();
#endif
public: public:
VirtualSpaceNode(size_t byte_size); VirtualSpaceNode(size_t byte_size);
@ -314,8 +315,10 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
void inc_top(size_t word_size) { _top += word_size; } void inc_top(size_t word_size) { _top += word_size; }
uintx container_count() { return _container_count; } uintx container_count() { return _container_count; }
void inc_container_count();
void dec_container_count(); void dec_container_count();
#ifdef ASSERT #ifdef ASSERT
uint container_count_slow();
void verify_container_count(); void verify_container_count();
#endif #endif
@ -421,8 +424,6 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
VirtualSpaceNode* _virtual_space_list; VirtualSpaceNode* _virtual_space_list;
// virtual space currently being used for allocations // virtual space currently being used for allocations
VirtualSpaceNode* _current_virtual_space; VirtualSpaceNode* _current_virtual_space;
// Free chunk list for all other metadata
ChunkManager _chunk_manager;
// Can this virtual list allocate >1 spaces? Also, used to determine // Can this virtual list allocate >1 spaces? Also, used to determine
// whether to allocate unlimited small chunks in this virtual space // whether to allocate unlimited small chunks in this virtual space
@ -475,7 +476,6 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
return _current_virtual_space; return _current_virtual_space;
} }
ChunkManager* chunk_manager() { return &_chunk_manager; }
bool is_class() const { return _is_class; } bool is_class() const { return _is_class; }
// Allocate the first virtualspace. // Allocate the first virtualspace.
@ -494,14 +494,7 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
void dec_virtual_space_count(); void dec_virtual_space_count();
// Unlink empty VirtualSpaceNodes and free it. // Unlink empty VirtualSpaceNodes and free it.
void purge(); void purge(ChunkManager* chunk_manager);
// Used and capacity in the entire list of virtual spaces.
// These are global values shared by all Metaspaces
size_t capacity_words_sum();
size_t capacity_bytes_sum() { return capacity_words_sum() * BytesPerWord; }
size_t used_words_sum();
size_t used_bytes_sum() { return used_words_sum() * BytesPerWord; }
bool contains(const void *ptr); bool contains(const void *ptr);
@ -582,18 +575,12 @@ class SpaceManager : public CHeapObj<mtClass> {
// Type of metadata allocated. // Type of metadata allocated.
Metaspace::MetadataType _mdtype; Metaspace::MetadataType _mdtype;
// Chunk related size
size_t _medium_chunk_bunch;
// List of chunks in use by this SpaceManager. Allocations // List of chunks in use by this SpaceManager. Allocations
// are done from the current chunk. The list is used for deallocating // are done from the current chunk. The list is used for deallocating
// chunks when the SpaceManager is freed. // chunks when the SpaceManager is freed.
Metachunk* _chunks_in_use[NumberOfInUseLists]; Metachunk* _chunks_in_use[NumberOfInUseLists];
Metachunk* _current_chunk; Metachunk* _current_chunk;
// Virtual space where allocation comes from.
VirtualSpaceList* _vs_list;
// Number of small chunks to allocate to a manager // Number of small chunks to allocate to a manager
// If class space manager, small chunks are unlimited // If class space manager, small chunks are unlimited
static uint const _small_chunk_limit; static uint const _small_chunk_limit;
@ -626,7 +613,9 @@ class SpaceManager : public CHeapObj<mtClass> {
} }
Metaspace::MetadataType mdtype() { return _mdtype; } Metaspace::MetadataType mdtype() { return _mdtype; }
VirtualSpaceList* vs_list() const { return _vs_list; }
VirtualSpaceList* vs_list() const { return Metaspace::get_space_list(_mdtype); }
ChunkManager* chunk_manager() const { return Metaspace::get_chunk_manager(_mdtype); }
Metachunk* current_chunk() const { return _current_chunk; } Metachunk* current_chunk() const { return _current_chunk; }
void set_current_chunk(Metachunk* v) { void set_current_chunk(Metachunk* v) {
@ -648,18 +637,19 @@ class SpaceManager : public CHeapObj<mtClass> {
public: public:
SpaceManager(Metaspace::MetadataType mdtype, SpaceManager(Metaspace::MetadataType mdtype,
Mutex* lock, Mutex* lock);
VirtualSpaceList* vs_list);
~SpaceManager(); ~SpaceManager();
enum ChunkMultiples { enum ChunkMultiples {
MediumChunkMultiple = 4 MediumChunkMultiple = 4
}; };
bool is_class() { return _mdtype == Metaspace::ClassType; }
// Accessors // Accessors
size_t specialized_chunk_size() { return SpecializedChunk; } size_t specialized_chunk_size() { return SpecializedChunk; }
size_t small_chunk_size() { return (size_t) vs_list()->is_class() ? ClassSmallChunk : SmallChunk; } size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; }
size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; } size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; }
size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; }
size_t allocated_blocks_words() const { return _allocated_blocks_words; } size_t allocated_blocks_words() const { return _allocated_blocks_words; }
@ -762,7 +752,7 @@ void VirtualSpaceNode::inc_container_count() {
_container_count++; _container_count++;
assert(_container_count == container_count_slow(), assert(_container_count == container_count_slow(),
err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT
"container_count_slow() " SIZE_FORMAT, " container_count_slow() " SIZE_FORMAT,
_container_count, container_count_slow())); _container_count, container_count_slow()));
} }
@ -775,7 +765,7 @@ void VirtualSpaceNode::dec_container_count() {
void VirtualSpaceNode::verify_container_count() { void VirtualSpaceNode::verify_container_count() {
assert(_container_count == container_count_slow(), assert(_container_count == container_count_slow(),
err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT
"container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow()));
} }
#endif #endif
@ -1020,7 +1010,7 @@ void ChunkManager::remove_chunk(Metachunk* chunk) {
// Walk the list of VirtualSpaceNodes and delete // Walk the list of VirtualSpaceNodes and delete
// nodes with a 0 container_count. Remove Metachunks in // nodes with a 0 container_count. Remove Metachunks in
// the node from their respective freelists. // the node from their respective freelists.
void VirtualSpaceList::purge() { void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
assert_lock_strong(SpaceManager::expand_lock()); assert_lock_strong(SpaceManager::expand_lock());
// Don't use a VirtualSpaceListIterator because this // Don't use a VirtualSpaceListIterator because this
// list is being changed and a straightforward use of an iterator is not safe. // list is being changed and a straightforward use of an iterator is not safe.
@ -1042,7 +1032,7 @@ void VirtualSpaceList::purge() {
prev_vsl->set_next(vsl->next()); prev_vsl->set_next(vsl->next());
} }
vsl->purge(chunk_manager()); vsl->purge(chunk_manager);
dec_reserved_words(vsl->reserved_words()); dec_reserved_words(vsl->reserved_words());
dec_committed_words(vsl->committed_words()); dec_committed_words(vsl->committed_words());
dec_virtual_space_count(); dec_virtual_space_count();
@ -1064,36 +1054,6 @@ void VirtualSpaceList::purge() {
#endif #endif
} }
size_t VirtualSpaceList::used_words_sum() {
size_t allocated_by_vs = 0;
VirtualSpaceListIterator iter(virtual_space_list());
while (iter.repeat()) {
VirtualSpaceNode* vsl = iter.get_next();
// Sum used region [bottom, top) in each virtualspace
allocated_by_vs += vsl->used_words_in_vs();
}
assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(),
err_msg("Total in free chunks " SIZE_FORMAT
" greater than total from virtual_spaces " SIZE_FORMAT,
allocated_by_vs, chunk_manager()->free_chunks_total_words()));
size_t used =
allocated_by_vs - chunk_manager()->free_chunks_total_words();
return used;
}
// Space available in all MetadataVirtualspaces allocated
// for metadata. This is the upper limit on the capacity
// of chunks allocated out of all the MetadataVirtualspaces.
size_t VirtualSpaceList::capacity_words_sum() {
size_t capacity = 0;
VirtualSpaceListIterator iter(virtual_space_list());
while (iter.repeat()) {
VirtualSpaceNode* vsl = iter.get_next();
capacity += vsl->capacity_words_in_vs();
}
return capacity;
}
VirtualSpaceList::VirtualSpaceList(size_t word_size ) : VirtualSpaceList::VirtualSpaceList(size_t word_size ) :
_is_class(false), _is_class(false),
_virtual_space_list(NULL), _virtual_space_list(NULL),
@ -1104,10 +1064,6 @@ VirtualSpaceList::VirtualSpaceList(size_t word_size ) :
MutexLockerEx cl(SpaceManager::expand_lock(), MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag); Mutex::_no_safepoint_check_flag);
bool initialization_succeeded = grow_vs(word_size); bool initialization_succeeded = grow_vs(word_size);
_chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
_chunk_manager.free_chunks(SmallIndex)->set_size(SmallChunk);
_chunk_manager.free_chunks(MediumIndex)->set_size(MediumChunk);
assert(initialization_succeeded, assert(initialization_succeeded,
" VirtualSpaceList initialization should not fail"); " VirtualSpaceList initialization should not fail");
} }
@ -1123,9 +1079,6 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
Mutex::_no_safepoint_check_flag); Mutex::_no_safepoint_check_flag);
VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs); VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs);
bool succeeded = class_entry->initialize(); bool succeeded = class_entry->initialize();
_chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
_chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk);
_chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk);
assert(succeeded, " VirtualSpaceList initialization should not fail"); assert(succeeded, " VirtualSpaceList initialization should not fail");
link_vs(class_entry); link_vs(class_entry);
} }
@ -1142,7 +1095,7 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) {
} }
// Reserve the space // Reserve the space
size_t vs_byte_size = vs_word_size * BytesPerWord; size_t vs_byte_size = vs_word_size * BytesPerWord;
assert(vs_byte_size % os::vm_page_size() == 0, "Not aligned"); assert(vs_byte_size % os::vm_allocation_granularity() == 0, "Not aligned");
// Allocate the meta virtual space and initialize it. // Allocate the meta virtual space and initialize it.
VirtualSpaceNode* new_entry = new VirtualSpaceNode(vs_byte_size); VirtualSpaceNode* new_entry = new VirtualSpaceNode(vs_byte_size);
@ -1195,15 +1148,8 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
size_t grow_chunks_by_words, size_t grow_chunks_by_words,
size_t medium_chunk_bunch) { size_t medium_chunk_bunch) {
// Get a chunk from the chunk freelist // Allocate a chunk out of the current virtual space.
Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); Metachunk* next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
if (next != NULL) {
next->container()->inc_container_count();
} else {
// Allocate a chunk out of the current virtual space.
next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
}
if (next == NULL) { if (next == NULL) {
// Not enough room in current virtual space. Try to commit // Not enough room in current virtual space. Try to commit
@ -1221,12 +1167,14 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
// being used for CompressedHeaders, don't allocate a new virtualspace. // being used for CompressedHeaders, don't allocate a new virtualspace.
if (can_grow() && MetaspaceGC::should_expand(this, word_size)) { if (can_grow() && MetaspaceGC::should_expand(this, word_size)) {
// Get another virtual space. // Get another virtual space.
size_t grow_vs_words = size_t allocation_aligned_expand_words =
MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words); align_size_up(aligned_expand_vs_by_words, os::vm_allocation_granularity() / BytesPerWord);
size_t grow_vs_words =
MAX2((size_t)VirtualSpaceSize, allocation_aligned_expand_words);
if (grow_vs(grow_vs_words)) { if (grow_vs(grow_vs_words)) {
// Got it. It's on the list now. Get a chunk from it. // Got it. It's on the list now. Get a chunk from it.
assert(current_virtual_space()->expanded_words() == 0, assert(current_virtual_space()->expanded_words() == 0,
"New virtuals space nodes should not have expanded"); "New virtual space nodes should not have expanded");
size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words, size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words,
page_size_words); page_size_words);
@ -1342,8 +1290,9 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) {
// reserved space, because this is a larger space prereserved for compressed // reserved space, because this is a larger space prereserved for compressed
// class pointers. // class pointers.
if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) {
size_t real_allocated = Metaspace::space_list()->reserved_words() + size_t nonclass_allocated = MetaspaceAux::reserved_bytes(Metaspace::NonClassType);
MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); size_t class_allocated = MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType);
size_t real_allocated = nonclass_allocated + class_allocated;
if (real_allocated >= MaxMetaspaceSize) { if (real_allocated >= MaxMetaspaceSize) {
return false; return false;
} }
@ -1536,15 +1485,15 @@ void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm,
if (dummy_chunk == NULL) { if (dummy_chunk == NULL) {
break; break;
} }
vsl->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); sm->chunk_manager()->chunk_freelist_deallocate(dummy_chunk);
if (TraceMetadataChunkAllocation && Verbose) { if (TraceMetadataChunkAllocation && Verbose) {
gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ", gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ",
sm->sum_count_in_chunks_in_use()); sm->sum_count_in_chunks_in_use());
dummy_chunk->print_on(gclog_or_tty); dummy_chunk->print_on(gclog_or_tty);
gclog_or_tty->print_cr(" Free chunks total %d count %d", gclog_or_tty->print_cr(" Free chunks total %d count %d",
vsl->chunk_manager()->free_chunks_total_words(), sm->chunk_manager()->free_chunks_total_words(),
vsl->chunk_manager()->free_chunks_count()); sm->chunk_manager()->free_chunks_count());
} }
} }
} else { } else {
@ -1796,6 +1745,8 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
// work. // work.
chunk->set_is_free(false); chunk->set_is_free(false);
#endif #endif
chunk->container()->inc_container_count();
slow_locked_verify(); slow_locked_verify();
return chunk; return chunk;
} }
@ -1830,9 +1781,9 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
return chunk; return chunk;
} }
void ChunkManager::print_on(outputStream* out) { void ChunkManager::print_on(outputStream* out) const {
if (PrintFLSStatistics != 0) { if (PrintFLSStatistics != 0) {
humongous_dictionary()->report_statistics(); const_cast<ChunkManager *>(this)->humongous_dictionary()->report_statistics();
} }
} }
@ -1979,8 +1930,8 @@ void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const {
} }
} }
vs_list()->chunk_manager()->locked_print_free_chunks(st); chunk_manager()->locked_print_free_chunks(st);
vs_list()->chunk_manager()->locked_print_sum_free_chunks(st); chunk_manager()->locked_print_sum_free_chunks(st);
} }
size_t SpaceManager::calc_chunk_size(size_t word_size) { size_t SpaceManager::calc_chunk_size(size_t word_size) {
@ -2084,9 +2035,7 @@ void SpaceManager::print_on(outputStream* st) const {
} }
SpaceManager::SpaceManager(Metaspace::MetadataType mdtype, SpaceManager::SpaceManager(Metaspace::MetadataType mdtype,
Mutex* lock, Mutex* lock) :
VirtualSpaceList* vs_list) :
_vs_list(vs_list),
_mdtype(mdtype), _mdtype(mdtype),
_allocated_blocks_words(0), _allocated_blocks_words(0),
_allocated_chunks_words(0), _allocated_chunks_words(0),
@ -2172,9 +2121,7 @@ SpaceManager::~SpaceManager() {
MutexLockerEx fcl(SpaceManager::expand_lock(), MutexLockerEx fcl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag); Mutex::_no_safepoint_check_flag);
ChunkManager* chunk_manager = vs_list()->chunk_manager(); chunk_manager()->slow_locked_verify();
chunk_manager->slow_locked_verify();
dec_total_from_size_metrics(); dec_total_from_size_metrics();
@ -2188,8 +2135,8 @@ SpaceManager::~SpaceManager() {
// Have to update before the chunks_in_use lists are emptied // Have to update before the chunks_in_use lists are emptied
// below. // below.
chunk_manager->inc_free_chunks_total(allocated_chunks_words(), chunk_manager()->inc_free_chunks_total(allocated_chunks_words(),
sum_count_in_chunks_in_use()); sum_count_in_chunks_in_use());
// Add all the chunks in use by this space manager // Add all the chunks in use by this space manager
// to the global list of free chunks. // to the global list of free chunks.
@ -2204,11 +2151,11 @@ SpaceManager::~SpaceManager() {
chunk_size_name(i)); chunk_size_name(i));
} }
Metachunk* chunks = chunks_in_use(i); Metachunk* chunks = chunks_in_use(i);
chunk_manager->return_chunks(i, chunks); chunk_manager()->return_chunks(i, chunks);
set_chunks_in_use(i, NULL); set_chunks_in_use(i, NULL);
if (TraceMetadataChunkAllocation && Verbose) { if (TraceMetadataChunkAllocation && Verbose) {
gclog_or_tty->print_cr("updated freelist count %d %s", gclog_or_tty->print_cr("updated freelist count %d %s",
chunk_manager->free_chunks(i)->count(), chunk_manager()->free_chunks(i)->count(),
chunk_size_name(i)); chunk_size_name(i));
} }
assert(i != HumongousIndex, "Humongous chunks are handled explicitly later"); assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
@ -2245,16 +2192,16 @@ SpaceManager::~SpaceManager() {
humongous_chunks->word_size(), HumongousChunkGranularity)); humongous_chunks->word_size(), HumongousChunkGranularity));
Metachunk* next_humongous_chunks = humongous_chunks->next(); Metachunk* next_humongous_chunks = humongous_chunks->next();
humongous_chunks->container()->dec_container_count(); humongous_chunks->container()->dec_container_count();
chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks);
humongous_chunks = next_humongous_chunks; humongous_chunks = next_humongous_chunks;
} }
if (TraceMetadataChunkAllocation && Verbose) { if (TraceMetadataChunkAllocation && Verbose) {
gclog_or_tty->print_cr(""); gclog_or_tty->print_cr("");
gclog_or_tty->print_cr("updated dictionary count %d %s", gclog_or_tty->print_cr("updated dictionary count %d %s",
chunk_manager->humongous_dictionary()->total_count(), chunk_manager()->humongous_dictionary()->total_count(),
chunk_size_name(HumongousIndex)); chunk_size_name(HumongousIndex));
} }
chunk_manager->slow_locked_verify(); chunk_manager()->slow_locked_verify();
} }
const char* SpaceManager::chunk_size_name(ChunkIndex index) const { const char* SpaceManager::chunk_size_name(ChunkIndex index) const {
@ -2343,9 +2290,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
gclog_or_tty->print("SpaceManager::add_chunk: %d) ", gclog_or_tty->print("SpaceManager::add_chunk: %d) ",
sum_count_in_chunks_in_use()); sum_count_in_chunks_in_use());
new_chunk->print_on(gclog_or_tty); new_chunk->print_on(gclog_or_tty);
if (vs_list() != NULL) { chunk_manager()->locked_print_free_chunks(gclog_or_tty);
vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty);
}
} }
} }
@ -2361,10 +2306,14 @@ void SpaceManager::retire_current_chunk() {
Metachunk* SpaceManager::get_new_chunk(size_t word_size, Metachunk* SpaceManager::get_new_chunk(size_t word_size,
size_t grow_chunks_by_words) { size_t grow_chunks_by_words) {
// Get a chunk from the chunk freelist
Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words);
Metachunk* next = vs_list()->get_new_chunk(word_size, if (next == NULL) {
grow_chunks_by_words, next = vs_list()->get_new_chunk(word_size,
medium_chunk_bunch()); grow_chunks_by_words,
medium_chunk_bunch());
}
if (TraceMetadataHumongousAllocation && next != NULL && if (TraceMetadataHumongousAllocation && next != NULL &&
SpaceManager::is_humongous(next->word_size())) { SpaceManager::is_humongous(next->word_size())) {
@ -2644,13 +2593,12 @@ size_t MetaspaceAux::committed_bytes(Metaspace::MetadataType mdtype) {
size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); }
size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) { size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) {
VirtualSpaceList* list = Metaspace::get_space_list(mdtype); ChunkManager* chunk_manager = Metaspace::get_chunk_manager(mdtype);
if (list == NULL) { if (chunk_manager == NULL) {
return 0; return 0;
} }
ChunkManager* chunk = list->chunk_manager(); chunk_manager->slow_verify();
chunk->slow_verify(); return chunk_manager->free_chunks_total_words();
return chunk->free_chunks_total_words();
} }
size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) { size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) {
@ -2801,9 +2749,9 @@ void MetaspaceAux::dump(outputStream* out) {
} }
void MetaspaceAux::verify_free_chunks() { void MetaspaceAux::verify_free_chunks() {
Metaspace::space_list()->chunk_manager()->verify(); Metaspace::chunk_manager_metadata()->verify();
if (Metaspace::using_class_space()) { if (Metaspace::using_class_space()) {
Metaspace::class_space_list()->chunk_manager()->verify(); Metaspace::chunk_manager_class()->verify();
} }
} }
@ -2874,6 +2822,9 @@ Metaspace::~Metaspace() {
VirtualSpaceList* Metaspace::_space_list = NULL; VirtualSpaceList* Metaspace::_space_list = NULL;
VirtualSpaceList* Metaspace::_class_space_list = NULL; VirtualSpaceList* Metaspace::_class_space_list = NULL;
ChunkManager* Metaspace::_chunk_manager_metadata = NULL;
ChunkManager* Metaspace::_chunk_manager_class = NULL;
#define VIRTUALSPACEMULTIPLIER 2 #define VIRTUALSPACEMULTIPLIER 2
#ifdef _LP64 #ifdef _LP64
@ -2981,6 +2932,7 @@ void Metaspace::initialize_class_space(ReservedSpace rs) {
err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize));
assert(using_class_space(), "Must be using class space"); assert(using_class_space(), "Must be using class space");
_class_space_list = new VirtualSpaceList(rs); _class_space_list = new VirtualSpaceList(rs);
_chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk);
} }
#endif #endif
@ -3006,6 +2958,7 @@ void Metaspace::global_initialize() {
// remainder is the misc code and data chunks. // remainder is the misc code and data chunks.
cds_total = FileMapInfo::shared_spaces_size(); cds_total = FileMapInfo::shared_spaces_size();
_space_list = new VirtualSpaceList(cds_total/wordSize); _space_list = new VirtualSpaceList(cds_total/wordSize);
_chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk);
#ifdef _LP64 #ifdef _LP64
// Set the compressed klass pointer base so that decoding of these pointers works // Set the compressed klass pointer base so that decoding of these pointers works
@ -3073,15 +3026,30 @@ void Metaspace::global_initialize() {
size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size(); size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size();
// Initialize the list of virtual spaces. // Initialize the list of virtual spaces.
_space_list = new VirtualSpaceList(word_size); _space_list = new VirtualSpaceList(word_size);
_chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk);
} }
} }
Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype,
size_t chunk_word_size,
size_t chunk_bunch) {
// Get a chunk from the chunk freelist
Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size);
if (chunk != NULL) {
return chunk;
}
return get_space_list(mdtype)->get_initialization_chunk(chunk_word_size, chunk_bunch);
}
void Metaspace::initialize(Mutex* lock, MetaspaceType type) { void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
assert(space_list() != NULL, assert(space_list() != NULL,
"Metadata VirtualSpaceList has not been initialized"); "Metadata VirtualSpaceList has not been initialized");
assert(chunk_manager_metadata() != NULL,
"Metadata ChunkManager has not been initialized");
_vsm = new SpaceManager(NonClassType, lock, space_list()); _vsm = new SpaceManager(NonClassType, lock);
if (_vsm == NULL) { if (_vsm == NULL) {
return; return;
} }
@ -3090,11 +3058,13 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size); vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size);
if (using_class_space()) { if (using_class_space()) {
assert(class_space_list() != NULL, assert(class_space_list() != NULL,
"Class VirtualSpaceList has not been initialized"); "Class VirtualSpaceList has not been initialized");
assert(chunk_manager_class() != NULL,
"Class ChunkManager has not been initialized");
// Allocate SpaceManager for classes. // Allocate SpaceManager for classes.
_class_vsm = new SpaceManager(ClassType, lock, class_space_list()); _class_vsm = new SpaceManager(ClassType, lock);
if (_class_vsm == NULL) { if (_class_vsm == NULL) {
return; return;
} }
@ -3103,9 +3073,9 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
// Allocate chunk for metadata objects // Allocate chunk for metadata objects
Metachunk* new_chunk = Metachunk* new_chunk = get_initialization_chunk(NonClassType,
space_list()->get_initialization_chunk(word_size, word_size,
vsm()->medium_chunk_bunch()); vsm()->medium_chunk_bunch());
assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks");
if (new_chunk != NULL) { if (new_chunk != NULL) {
// Add to this manager's list of chunks in use and current_chunk(). // Add to this manager's list of chunks in use and current_chunk().
@ -3114,9 +3084,9 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
// Allocate chunk for class metadata objects // Allocate chunk for class metadata objects
if (using_class_space()) { if (using_class_space()) {
Metachunk* class_chunk = Metachunk* class_chunk = get_initialization_chunk(ClassType,
class_space_list()->get_initialization_chunk(class_word_size, class_word_size,
class_vsm()->medium_chunk_bunch()); class_vsm()->medium_chunk_bunch());
if (class_chunk != NULL) { if (class_chunk != NULL) {
class_vsm()->add_chunk(class_chunk, true); class_vsm()->add_chunk(class_chunk, true);
} }
@ -3333,12 +3303,16 @@ void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) {
} }
} }
void Metaspace::purge(MetadataType mdtype) {
get_space_list(mdtype)->purge(get_chunk_manager(mdtype));
}
void Metaspace::purge() { void Metaspace::purge() {
MutexLockerEx cl(SpaceManager::expand_lock(), MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag); Mutex::_no_safepoint_check_flag);
space_list()->purge(); purge(NonClassType);
if (using_class_space()) { if (using_class_space()) {
class_space_list()->purge(); purge(ClassType);
} }
} }
@ -3385,7 +3359,7 @@ void Metaspace::dump(outputStream* const out) const {
#ifndef PRODUCT #ifndef PRODUCT
class MetaspaceAuxTest : AllStatic { class TestMetaspaceAuxTest : AllStatic {
public: public:
static void test_reserved() { static void test_reserved() {
size_t reserved = MetaspaceAux::reserved_bytes(); size_t reserved = MetaspaceAux::reserved_bytes();
@ -3425,14 +3399,25 @@ class MetaspaceAuxTest : AllStatic {
} }
} }
static void test_virtual_space_list_large_chunk() {
VirtualSpaceList* vs_list = new VirtualSpaceList(os::vm_allocation_granularity());
MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
// A size larger than VirtualSpaceSize (256k) and add one page to make it _not_ be
// vm_allocation_granularity aligned on Windows.
size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord));
large_size += (os::vm_page_size()/BytesPerWord);
vs_list->get_new_chunk(large_size, large_size, 0);
}
static void test() { static void test() {
test_reserved(); test_reserved();
test_committed(); test_committed();
test_virtual_space_list_large_chunk();
} }
}; };
void MetaspaceAux_test() { void TestMetaspaceAux_test() {
MetaspaceAuxTest::test(); TestMetaspaceAuxTest::test();
} }
#endif #endif

View File

@ -56,12 +56,15 @@
// +-------------------+ // +-------------------+
// //
class ChunkManager;
class ClassLoaderData; class ClassLoaderData;
class Metablock; class Metablock;
class Metachunk;
class MetaWord; class MetaWord;
class Mutex; class Mutex;
class outputStream; class outputStream;
class SpaceManager; class SpaceManager;
class VirtualSpaceList;
// Metaspaces each have a SpaceManager and allocations // Metaspaces each have a SpaceManager and allocations
// are done by the SpaceManager. Allocations are done // are done by the SpaceManager. Allocations are done
@ -76,8 +79,6 @@ class SpaceManager;
// allocate() method returns a block for use as a // allocate() method returns a block for use as a
// quantum of metadata. // quantum of metadata.
class VirtualSpaceList;
class Metaspace : public CHeapObj<mtClass> { class Metaspace : public CHeapObj<mtClass> {
friend class VMStructs; friend class VMStructs;
friend class SpaceManager; friend class SpaceManager;
@ -102,6 +103,10 @@ class Metaspace : public CHeapObj<mtClass> {
private: private:
void initialize(Mutex* lock, MetaspaceType type); void initialize(Mutex* lock, MetaspaceType type);
Metachunk* get_initialization_chunk(MetadataType mdtype,
size_t chunk_word_size,
size_t chunk_bunch);
// Align up the word size to the allocation word size // Align up the word size to the allocation word size
static size_t align_word_size_up(size_t); static size_t align_word_size_up(size_t);
@ -134,6 +139,10 @@ class Metaspace : public CHeapObj<mtClass> {
static VirtualSpaceList* _space_list; static VirtualSpaceList* _space_list;
static VirtualSpaceList* _class_space_list; static VirtualSpaceList* _class_space_list;
static ChunkManager* _chunk_manager_metadata;
static ChunkManager* _chunk_manager_class;
public:
static VirtualSpaceList* space_list() { return _space_list; } static VirtualSpaceList* space_list() { return _space_list; }
static VirtualSpaceList* class_space_list() { return _class_space_list; } static VirtualSpaceList* class_space_list() { return _class_space_list; }
static VirtualSpaceList* get_space_list(MetadataType mdtype) { static VirtualSpaceList* get_space_list(MetadataType mdtype) {
@ -141,6 +150,14 @@ class Metaspace : public CHeapObj<mtClass> {
return mdtype == ClassType ? class_space_list() : space_list(); return mdtype == ClassType ? class_space_list() : space_list();
} }
static ChunkManager* chunk_manager_metadata() { return _chunk_manager_metadata; }
static ChunkManager* chunk_manager_class() { return _chunk_manager_class; }
static ChunkManager* get_chunk_manager(MetadataType mdtype) {
assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata();
}
private:
// This is used by DumpSharedSpaces only, where only _vsm is used. So we will // This is used by DumpSharedSpaces only, where only _vsm is used. So we will
// maintain a single list for now. // maintain a single list for now.
void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size); void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
@ -199,6 +216,7 @@ class Metaspace : public CHeapObj<mtClass> {
void dump(outputStream* const out) const; void dump(outputStream* const out) const;
// Free empty virtualspaces // Free empty virtualspaces
static void purge(MetadataType mdtype);
static void purge(); static void purge();
void print_on(outputStream* st) const; void print_on(outputStream* st) const;

View File

@ -103,9 +103,10 @@ static void calculate_fingerprints() {
if (k->oop_is_instance()) { if (k->oop_is_instance()) {
InstanceKlass* ik = InstanceKlass::cast(k); InstanceKlass* ik = InstanceKlass::cast(k);
for (int i = 0; i < ik->methods()->length(); i++) { for (int i = 0; i < ik->methods()->length(); i++) {
ResourceMark rm;
Method* m = ik->methods()->at(i); Method* m = ik->methods()->at(i);
(new Fingerprinter(m))->fingerprint(); Fingerprinter fp(m);
// The side effect of this call sets method's fingerprint field.
fp.fingerprint();
} }
} }
} }

View File

@ -108,16 +108,16 @@ objArrayOop ConstantPool::resolved_references() const {
void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data, void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
intStack reference_map, intStack reference_map,
int constant_pool_map_length, int constant_pool_map_length,
TRAPS) { TRAPS) {
// Initialized the resolved object cache. // Initialized the resolved object cache.
int map_length = reference_map.length(); int map_length = reference_map.length();
if (map_length > 0) { if (map_length > 0) {
// Only need mapping back to constant pool entries. The map isn't used for // Only need mapping back to constant pool entries. The map isn't used for
// invokedynamic resolved_reference entries. The constant pool cache index // invokedynamic resolved_reference entries. For invokedynamic entries,
// has the mapping back to both the constant pool and to the resolved // the constant pool cache index has the mapping back to both the constant
// reference index. // pool and to the resolved reference index.
if (constant_pool_map_length > 0) { if (constant_pool_map_length > 0) {
Array<u2>* om = MetadataFactory::new_array<u2>(loader_data, map_length, CHECK); Array<u2>* om = MetadataFactory::new_array<u2>(loader_data, constant_pool_map_length, CHECK);
for (int i = 0; i < constant_pool_map_length; i++) { for (int i = 0; i < constant_pool_map_length; i++) {
int x = reference_map.at(i); int x = reference_map.at(i);
@ -182,16 +182,9 @@ oop ConstantPool::lock() {
int ConstantPool::cp_to_object_index(int cp_index) { int ConstantPool::cp_to_object_index(int cp_index) {
// this is harder don't do this so much. // this is harder don't do this so much.
for (int i = 0; i< reference_map()->length(); i++) { int i = reference_map()->find(cp_index);
if (reference_map()->at(i) == cp_index) return i; // We might not find the index for jsr292 call.
// Zero entry is divider between constant pool indices for strings, return (i < 0) ? _no_index_sentinel : i;
// method handles and method types. After that the index is a constant
// pool cache index for invokedynamic. Stop when zero (which can never
// be a constant pool index)
if (reference_map()->at(i) == 0) break;
}
// We might not find the index.
return _no_index_sentinel;
} }
Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) { Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
@ -840,8 +833,7 @@ oop ConstantPool::string_at_impl(constantPoolHandle this_oop, int which, int obj
// If the string has already been interned, this entry will be non-null // If the string has already been interned, this entry will be non-null
oop str = this_oop->resolved_references()->obj_at(obj_index); oop str = this_oop->resolved_references()->obj_at(obj_index);
if (str != NULL) return str; if (str != NULL) return str;
Symbol* sym = this_oop->unresolved_string_at(which);
Symbol* sym = this_oop->unresolved_string_at(which);
str = StringTable::intern(sym, CHECK_(NULL)); str = StringTable::intern(sym, CHECK_(NULL));
this_oop->string_at_put(which, obj_index, str); this_oop->string_at_put(which, obj_index, str);
assert(java_lang_String::is_instance(str), "must be string"); assert(java_lang_String::is_instance(str), "must be string");
@ -1619,9 +1611,11 @@ jint ConstantPool::cpool_entry_size(jint idx) {
case JVM_CONSTANT_UnresolvedClassInError: case JVM_CONSTANT_UnresolvedClassInError:
case JVM_CONSTANT_StringIndex: case JVM_CONSTANT_StringIndex:
case JVM_CONSTANT_MethodType: case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError:
return 3; return 3;
case JVM_CONSTANT_MethodHandle: case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError:
return 4; //tag, ref_kind, ref_index return 4; //tag, ref_kind, ref_index
case JVM_CONSTANT_Integer: case JVM_CONSTANT_Integer:
@ -1802,8 +1796,8 @@ int ConstantPool::copy_cpool_bytes(int cpool_size,
case JVM_CONSTANT_MethodHandle: case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError: { case JVM_CONSTANT_MethodHandleInError: {
*bytes = JVM_CONSTANT_MethodHandle; *bytes = JVM_CONSTANT_MethodHandle;
int kind = method_handle_ref_kind_at(idx); int kind = method_handle_ref_kind_at_error_ok(idx);
idx1 = method_handle_index_at(idx); idx1 = method_handle_index_at_error_ok(idx);
*(bytes+1) = (unsigned char) kind; *(bytes+1) = (unsigned char) kind;
Bytes::put_Java_u2((address) (bytes+2), idx1); Bytes::put_Java_u2((address) (bytes+2), idx1);
DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1)); DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1));
@ -1812,7 +1806,7 @@ int ConstantPool::copy_cpool_bytes(int cpool_size,
case JVM_CONSTANT_MethodType: case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError: { case JVM_CONSTANT_MethodTypeInError: {
*bytes = JVM_CONSTANT_MethodType; *bytes = JVM_CONSTANT_MethodType;
idx1 = method_type_index_at(idx); idx1 = method_type_index_at_error_ok(idx);
Bytes::put_Java_u2((address) (bytes+1), idx1); Bytes::put_Java_u2((address) (bytes+1), idx1);
DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
break; break;
@ -2000,12 +1994,12 @@ void ConstantPool::print_entry_on(const int index, outputStream* st) {
break; break;
case JVM_CONSTANT_MethodHandle : case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodHandleInError : case JVM_CONSTANT_MethodHandleInError :
st->print("ref_kind=%d", method_handle_ref_kind_at(index)); st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index));
st->print(" ref_index=%d", method_handle_index_at(index)); st->print(" ref_index=%d", method_handle_index_at_error_ok(index));
break; break;
case JVM_CONSTANT_MethodType : case JVM_CONSTANT_MethodType :
case JVM_CONSTANT_MethodTypeInError : case JVM_CONSTANT_MethodTypeInError :
st->print("signature_index=%d", method_type_index_at(index)); st->print("signature_index=%d", method_type_index_at_error_ok(index));
break; break;
case JVM_CONSTANT_InvokeDynamic : case JVM_CONSTANT_InvokeDynamic :
{ {

View File

@ -231,7 +231,6 @@ class ConstantPool : public Metadata {
static int cache_offset_in_bytes() { return offset_of(ConstantPool, _cache); } static int cache_offset_in_bytes() { return offset_of(ConstantPool, _cache); }
static int pool_holder_offset_in_bytes() { return offset_of(ConstantPool, _pool_holder); } static int pool_holder_offset_in_bytes() { return offset_of(ConstantPool, _pool_holder); }
static int resolved_references_offset_in_bytes() { return offset_of(ConstantPool, _resolved_references); } static int resolved_references_offset_in_bytes() { return offset_of(ConstantPool, _resolved_references); }
static int reference_map_offset_in_bytes() { return offset_of(ConstantPool, _reference_map); }
// Storing constants // Storing constants
@ -475,18 +474,42 @@ class ConstantPool : public Metadata {
return *int_at_addr(which); return *int_at_addr(which);
} }
int method_handle_ref_kind_at(int which) { private:
assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); int method_handle_ref_kind_at(int which, bool error_ok) {
assert(tag_at(which).is_method_handle() ||
(error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits
} }
int method_handle_index_at(int which) { int method_handle_index_at(int which, bool error_ok) {
assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); assert(tag_at(which).is_method_handle() ||
(error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits
} }
int method_type_index_at(int which) { int method_type_index_at(int which, bool error_ok) {
assert(tag_at(which).is_method_type(), "Corrupted constant pool"); assert(tag_at(which).is_method_type() ||
(error_ok && tag_at(which).is_method_type_in_error()), "Corrupted constant pool");
return *int_at_addr(which); return *int_at_addr(which);
} }
public:
int method_handle_ref_kind_at(int which) {
return method_handle_ref_kind_at(which, false);
}
int method_handle_ref_kind_at_error_ok(int which) {
return method_handle_ref_kind_at(which, true);
}
int method_handle_index_at(int which) {
return method_handle_index_at(which, false);
}
int method_handle_index_at_error_ok(int which) {
return method_handle_index_at(which, true);
}
int method_type_index_at(int which) {
return method_type_index_at(which, false);
}
int method_type_index_at_error_ok(int which) {
return method_type_index_at(which, true);
}
// Derived queries: // Derived queries:
Symbol* method_handle_name_ref_at(int which) { Symbol* method_handle_name_ref_at(int which) {
int member = method_handle_index_at(which); int member = method_handle_index_at(which);

View File

@ -2769,24 +2769,17 @@ void InstanceKlass::print_on(outputStream* st) const {
st->print(BULLET"field annotations: "); fields_annotations()->print_value_on(st); st->cr(); st->print(BULLET"field annotations: "); fields_annotations()->print_value_on(st); st->cr();
st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr(); st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr();
{ {
ResourceMark rm; bool have_pv = false;
// PreviousVersionInfo objects returned via PreviousVersionWalker PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this);
// contain a GrowableArray of handles. We have to clean up the for (PreviousVersionNode * pv_node = pvw.next_previous_version();
// GrowableArray _after_ the PreviousVersionWalker destructor pv_node != NULL; pv_node = pvw.next_previous_version()) {
// has destroyed the handles. if (!have_pv)
{ st->print(BULLET"previous version: ");
bool have_pv = false; have_pv = true;
PreviousVersionWalker pvw((InstanceKlass*)this); pv_node->prev_constant_pool()->print_value_on(st);
for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); }
pv_info != NULL; pv_info = pvw.next_previous_version()) { if (have_pv) st->cr();
if (!have_pv) } // pvw is cleaned up
st->print(BULLET"previous version: ");
have_pv = true;
pv_info->prev_constant_pool_handle()()->print_value_on(st);
}
if (have_pv) st->cr();
} // pvw is cleaned up
} // rm is cleaned up
if (generic_signature() != NULL) { if (generic_signature() != NULL) {
st->print(BULLET"generic signature: "); st->print(BULLET"generic signature: ");
@ -3317,34 +3310,34 @@ void InstanceKlass::add_previous_version(instanceKlassHandle ikh,
Array<Method*>* old_methods = ikh->methods(); Array<Method*>* old_methods = ikh->methods();
if (cp_ref->on_stack()) { if (cp_ref->on_stack()) {
PreviousVersionNode * pv_node = NULL; PreviousVersionNode * pv_node = NULL;
if (emcp_method_count == 0) { if (emcp_method_count == 0) {
// non-shared ConstantPool gets a reference // non-shared ConstantPool gets a reference
pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), NULL); pv_node = new PreviousVersionNode(cp_ref, NULL);
RC_TRACE(0x00000400, RC_TRACE(0x00000400,
("add: all methods are obsolete; flushing any EMCP refs")); ("add: all methods are obsolete; flushing any EMCP refs"));
} else { } else {
int local_count = 0; int local_count = 0;
GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass)
GrowableArray<Method*>(emcp_method_count, true); GrowableArray<Method*>(emcp_method_count, true);
for (int i = 0; i < old_methods->length(); i++) { for (int i = 0; i < old_methods->length(); i++) {
if (emcp_methods->at(i)) { if (emcp_methods->at(i)) {
// this old method is EMCP. Save it only if it's on the stack // this old method is EMCP. Save it only if it's on the stack
Method* old_method = old_methods->at(i); Method* old_method = old_methods->at(i);
if (old_method->on_stack()) { if (old_method->on_stack()) {
method_refs->append(old_method); method_refs->append(old_method);
}
if (++local_count >= emcp_method_count) {
// no more EMCP methods so bail out now
break;
} }
if (++local_count >= emcp_method_count) {
// no more EMCP methods so bail out now
break;
} }
} }
}
// non-shared ConstantPool gets a reference // non-shared ConstantPool gets a reference
pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), method_refs); pv_node = new PreviousVersionNode(cp_ref, method_refs);
} }
// append new previous version. // append new previous version.
_previous_versions->append(pv_node); _previous_versions->append(pv_node);
} }
// Since the caller is the VMThread and we are at a safepoint, this // Since the caller is the VMThread and we are at a safepoint, this
@ -3445,6 +3438,8 @@ Method* InstanceKlass::method_with_idnum(int idnum) {
return m; return m;
} }
} }
// None found, return null for the caller to handle.
return NULL;
} }
return m; return m;
} }
@ -3461,10 +3456,9 @@ unsigned char * InstanceKlass::get_cached_class_file_bytes() {
// Construct a PreviousVersionNode entry for the array hung off // Construct a PreviousVersionNode entry for the array hung off
// the InstanceKlass. // the InstanceKlass.
PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool, PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool,
bool prev_cp_is_weak, GrowableArray<Method*>* prev_EMCP_methods) { GrowableArray<Method*>* prev_EMCP_methods) {
_prev_constant_pool = prev_constant_pool; _prev_constant_pool = prev_constant_pool;
_prev_cp_is_weak = prev_cp_is_weak;
_prev_EMCP_methods = prev_EMCP_methods; _prev_EMCP_methods = prev_EMCP_methods;
} }
@ -3480,99 +3474,38 @@ PreviousVersionNode::~PreviousVersionNode() {
} }
} }
// Construct a PreviousVersionInfo entry
PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) {
_prev_constant_pool_handle = constantPoolHandle(); // NULL handle
_prev_EMCP_method_handles = NULL;
ConstantPool* cp = pv_node->prev_constant_pool();
assert(cp != NULL, "constant pool ref was unexpectedly cleared");
if (cp == NULL) {
return; // robustness
}
// make the ConstantPool* safe to return
_prev_constant_pool_handle = constantPoolHandle(cp);
GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods();
if (method_refs == NULL) {
// the InstanceKlass did not have any EMCP methods
return;
}
_prev_EMCP_method_handles = new GrowableArray<methodHandle>(10);
int n_methods = method_refs->length();
for (int i = 0; i < n_methods; i++) {
Method* method = method_refs->at(i);
assert (method != NULL, "method has been cleared");
if (method == NULL) {
continue; // robustness
}
// make the Method* safe to return
_prev_EMCP_method_handles->append(methodHandle(method));
}
}
// Destroy a PreviousVersionInfo
PreviousVersionInfo::~PreviousVersionInfo() {
// Since _prev_EMCP_method_handles is not C-heap allocated, we
// don't have to delete it.
}
// Construct a helper for walking the previous versions array // Construct a helper for walking the previous versions array
PreviousVersionWalker::PreviousVersionWalker(InstanceKlass *ik) { PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) {
_thread = thread;
_previous_versions = ik->previous_versions(); _previous_versions = ik->previous_versions();
_current_index = 0; _current_index = 0;
// _hm needs no initialization
_current_p = NULL; _current_p = NULL;
} _current_constant_pool_handle = constantPoolHandle(thread, ik->constants());
// Destroy a PreviousVersionWalker
PreviousVersionWalker::~PreviousVersionWalker() {
// Delete the current info just in case the caller didn't walk to
// the end of the previous versions list. No harm if _current_p is
// already NULL.
delete _current_p;
// When _hm is destroyed, all the Handles returned in
// PreviousVersionInfo objects will be destroyed.
// Also, after this destructor is finished it will be
// safe to delete the GrowableArray allocated in the
// PreviousVersionInfo objects.
} }
// Return the interesting information for the next previous version // Return the interesting information for the next previous version
// of the klass. Returns NULL if there are no more previous versions. // of the klass. Returns NULL if there are no more previous versions.
PreviousVersionInfo* PreviousVersionWalker::next_previous_version() { PreviousVersionNode* PreviousVersionWalker::next_previous_version() {
if (_previous_versions == NULL) { if (_previous_versions == NULL) {
// no previous versions so nothing to return // no previous versions so nothing to return
return NULL; return NULL;
} }
delete _current_p; // cleanup the previous info for the caller _current_p = NULL; // reset to NULL
_current_p = NULL; // reset to NULL so we don't delete same object twice _current_constant_pool_handle = NULL;
int length = _previous_versions->length(); int length = _previous_versions->length();
while (_current_index < length) { while (_current_index < length) {
PreviousVersionNode * pv_node = _previous_versions->at(_current_index++); PreviousVersionNode * pv_node = _previous_versions->at(_current_index++);
PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP, mtClass)
PreviousVersionInfo(pv_node);
constantPoolHandle cp_h = pv_info->prev_constant_pool_handle(); // Save a handle to the constant pool for this previous version,
assert (!cp_h.is_null(), "null cp found in previous version"); // which keeps all the methods from being deallocated.
_current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool());
// The caller will need to delete pv_info when they are done with it. _current_p = pv_node;
_current_p = pv_info; return pv_node;
return pv_info;
} }
// all of the underlying nodes' info has been deleted
return NULL; return NULL;
} // end next_previous_version() } // end next_previous_version()

View File

@ -1126,21 +1126,11 @@ class BreakpointInfo;
// A collection point for interesting information about the previous // A collection point for interesting information about the previous
// version(s) of an InstanceKlass. This class uses weak references to // version(s) of an InstanceKlass. A GrowableArray of PreviousVersionNodes
// the information so that the information may be collected as needed // is attached to the InstanceKlass as needed. See PreviousVersionWalker below.
// by the system. If the information is shared, then a regular
// reference must be used because a weak reference would be seen as
// collectible. A GrowableArray of PreviousVersionNodes is attached
// to the InstanceKlass as needed. See PreviousVersionWalker below.
class PreviousVersionNode : public CHeapObj<mtClass> { class PreviousVersionNode : public CHeapObj<mtClass> {
private: private:
// A shared ConstantPool is never collected so we'll always have ConstantPool* _prev_constant_pool;
// a reference to it so we can update items in the cache. We'll
// have a weak reference to a non-shared ConstantPool until all
// of the methods (EMCP or obsolete) have been collected; the
// non-shared ConstantPool becomes collectible at that point.
ConstantPool* _prev_constant_pool; // regular or weak reference
bool _prev_cp_is_weak; // true if not a shared ConstantPool
// If the previous version of the InstanceKlass doesn't have any // If the previous version of the InstanceKlass doesn't have any
// EMCP methods, then _prev_EMCP_methods will be NULL. If all the // EMCP methods, then _prev_EMCP_methods will be NULL. If all the
@ -1149,8 +1139,8 @@ class PreviousVersionNode : public CHeapObj<mtClass> {
GrowableArray<Method*>* _prev_EMCP_methods; GrowableArray<Method*>* _prev_EMCP_methods;
public: public:
PreviousVersionNode(ConstantPool* prev_constant_pool, bool prev_cp_is_weak, PreviousVersionNode(ConstantPool* prev_constant_pool,
GrowableArray<Method*>* prev_EMCP_methods); GrowableArray<Method*>* prev_EMCP_methods);
~PreviousVersionNode(); ~PreviousVersionNode();
ConstantPool* prev_constant_pool() const { ConstantPool* prev_constant_pool() const {
return _prev_constant_pool; return _prev_constant_pool;
@ -1161,59 +1151,26 @@ public:
}; };
// A Handle-ized version of PreviousVersionNode. // Helper object for walking previous versions.
class PreviousVersionInfo : public ResourceObj {
private:
constantPoolHandle _prev_constant_pool_handle;
// If the previous version of the InstanceKlass doesn't have any
// EMCP methods, then _prev_EMCP_methods will be NULL. Since the
// methods cannot be collected while we hold a handle,
// _prev_EMCP_methods should never have a length of zero.
GrowableArray<methodHandle>* _prev_EMCP_method_handles;
public:
PreviousVersionInfo(PreviousVersionNode *pv_node);
~PreviousVersionInfo();
constantPoolHandle prev_constant_pool_handle() const {
return _prev_constant_pool_handle;
}
GrowableArray<methodHandle>* prev_EMCP_method_handles() const {
return _prev_EMCP_method_handles;
}
};
// Helper object for walking previous versions. This helper cleans up
// the Handles that it allocates when the helper object is destroyed.
// The PreviousVersionInfo object returned by next_previous_version()
// is only valid until a subsequent call to next_previous_version() or
// the helper object is destroyed.
class PreviousVersionWalker : public StackObj { class PreviousVersionWalker : public StackObj {
private: private:
Thread* _thread;
GrowableArray<PreviousVersionNode *>* _previous_versions; GrowableArray<PreviousVersionNode *>* _previous_versions;
int _current_index; int _current_index;
// Fields for cleaning up when we are done walking the previous versions:
// A HandleMark for the PreviousVersionInfo handles:
HandleMark _hm;
// It would be nice to have a ResourceMark field in this helper also, // A pointer to the current node object so we can handle the deletes.
// but the ResourceMark code says to be careful to delete handles held PreviousVersionNode* _current_p;
// in GrowableArrays _before_ deleting the GrowableArray. Since we
// can't guarantee the order in which the fields are destroyed, we
// have to let the creator of the PreviousVersionWalker object do
// the right thing. Also, adding a ResourceMark here causes an
// include loop.
// A pointer to the current info object so we can handle the deletes. // The constant pool handle keeps all the methods in this class from being
PreviousVersionInfo * _current_p; // deallocated from the metaspace during class unloading.
constantPoolHandle _current_constant_pool_handle;
public: public:
PreviousVersionWalker(InstanceKlass *ik); PreviousVersionWalker(Thread* thread, InstanceKlass *ik);
~PreviousVersionWalker();
// Return the interesting information for the next previous version // Return the interesting information for the next previous version
// of the klass. Returns NULL if there are no more previous versions. // of the klass. Returns NULL if there are no more previous versions.
PreviousVersionInfo* next_previous_version(); PreviousVersionNode* next_previous_version();
}; };

View File

@ -123,7 +123,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
// Allows targeted inlining // Allows targeted inlining
if(callee_method->should_inline()) { if(callee_method->should_inline()) {
*wci_result = *(WarmCallInfo::always_hot()); *wci_result = *(WarmCallInfo::always_hot());
if (PrintInlining && Verbose) { if (C->print_inlining() && Verbose) {
CompileTask::print_inline_indent(inline_level()); CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined method is hot: "); tty->print_cr("Inlined method is hot: ");
} }
@ -137,7 +137,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
if(callee_method->interpreter_throwout_count() > InlineThrowCount && if(callee_method->interpreter_throwout_count() > InlineThrowCount &&
size < InlineThrowMaxSize ) { size < InlineThrowMaxSize ) {
wci_result->set_profit(wci_result->profit() * 100); wci_result->set_profit(wci_result->profit() * 100);
if (PrintInlining && Verbose) { if (C->print_inlining() && Verbose) {
CompileTask::print_inline_indent(inline_level()); CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count());
} }
@ -491,7 +491,7 @@ void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci,
C->log()->inline_fail(inline_msg); C->log()->inline_fail(inline_msg);
} }
} }
if (PrintInlining) { if (C->print_inlining()) {
C->print_inlining(callee_method, inline_level(), caller_bci, inline_msg); C->print_inlining(callee_method, inline_level(), caller_bci, inline_msg);
if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
if (Verbose && callee_method) { if (Verbose && callee_method) {
@ -540,7 +540,7 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
#ifndef PRODUCT #ifndef PRODUCT
if (UseOldInlining && InlineWarmCalls if (UseOldInlining && InlineWarmCalls
&& (PrintOpto || PrintOptoInlining || PrintInlining)) { && (PrintOpto || C->print_inlining())) {
bool cold = wci.is_cold(); bool cold = wci.is_cold();
bool hot = !cold && wci.is_hot(); bool hot = !cold && wci.is_hot();
bool old_cold = !success; bool old_cold = !success;
@ -617,7 +617,7 @@ InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, J
callee_method->is_compiled_lambda_form()) { callee_method->is_compiled_lambda_form()) {
max_inline_level_adjust += 1; // don't count method handle calls from java.lang.invoke implem max_inline_level_adjust += 1; // don't count method handle calls from java.lang.invoke implem
} }
if (max_inline_level_adjust != 0 && PrintInlining && (Verbose || WizardMode)) { if (max_inline_level_adjust != 0 && C->print_inlining() && (Verbose || WizardMode)) {
CompileTask::print_inline_indent(inline_level()); CompileTask::print_inline_indent(inline_level());
tty->print_cr(" \\-> discounting inline depth"); tty->print_cr(" \\-> discounting inline depth");
} }

View File

@ -159,8 +159,9 @@ class CallGenerator : public ResourceObj {
virtual void print_inlining_late(const char* msg) { ShouldNotReachHere(); } virtual void print_inlining_late(const char* msg) { ShouldNotReachHere(); }
static void print_inlining(Compile* C, ciMethod* callee, int inline_level, int bci, const char* msg) { static void print_inlining(Compile* C, ciMethod* callee, int inline_level, int bci, const char* msg) {
if (PrintInlining) if (C->print_inlining()) {
C->print_inlining(callee, inline_level, bci, msg); C->print_inlining(callee, inline_level, bci, msg);
}
} }
}; };

View File

@ -654,7 +654,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
_inlining_progress(false), _inlining_progress(false),
_inlining_incrementally(false), _inlining_incrementally(false),
_print_inlining_list(NULL), _print_inlining_list(NULL),
_print_inlining(0) { _print_inlining_idx(0) {
C = this; C = this;
CompileWrapper cw(this); CompileWrapper cw(this);
@ -679,6 +679,8 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
set_print_assembly(print_opto_assembly); set_print_assembly(print_opto_assembly);
set_parsed_irreducible_loop(false); set_parsed_irreducible_loop(false);
#endif #endif
set_print_inlining(PrintInlining || method()->has_option("PrintInlining") NOT_PRODUCT( || PrintOptoInlining));
set_print_intrinsics(PrintIntrinsics || method()->has_option("PrintIntrinsics"));
if (ProfileTraps) { if (ProfileTraps) {
// Make sure the method being compiled gets its own MDO, // Make sure the method being compiled gets its own MDO,
@ -710,7 +712,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
PhaseGVN gvn(node_arena(), estimated_size); PhaseGVN gvn(node_arena(), estimated_size);
set_initial_gvn(&gvn); set_initial_gvn(&gvn);
if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { if (print_inlining() || print_intrinsics()) {
_print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer()); _print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer());
} }
{ // Scope for timing the parser { // Scope for timing the parser
@ -937,7 +939,7 @@ Compile::Compile( ciEnv* ci_env,
_inlining_progress(false), _inlining_progress(false),
_inlining_incrementally(false), _inlining_incrementally(false),
_print_inlining_list(NULL), _print_inlining_list(NULL),
_print_inlining(0) { _print_inlining_idx(0) {
C = this; C = this;
#ifndef PRODUCT #ifndef PRODUCT
@ -3611,7 +3613,7 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n
} }
void Compile::dump_inlining() { void Compile::dump_inlining() {
if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { if (print_inlining() || print_intrinsics()) {
// Print inlining message for candidates that we couldn't inline // Print inlining message for candidates that we couldn't inline
// for lack of space or non constant receiver // for lack of space or non constant receiver
for (int i = 0; i < _late_inlines.length(); i++) { for (int i = 0; i < _late_inlines.length(); i++) {
@ -3635,7 +3637,7 @@ void Compile::dump_inlining() {
} }
} }
for (int i = 0; i < _print_inlining_list->length(); i++) { for (int i = 0; i < _print_inlining_list->length(); i++) {
tty->print(_print_inlining_list->at(i).ss()->as_string()); tty->print(_print_inlining_list->adr_at(i)->ss()->as_string());
} }
} }
} }

View File

@ -312,6 +312,8 @@ class Compile : public Phase {
bool _do_method_data_update; // True if we generate code to update MethodData*s bool _do_method_data_update; // True if we generate code to update MethodData*s
int _AliasLevel; // Locally-adjusted version of AliasLevel flag. int _AliasLevel; // Locally-adjusted version of AliasLevel flag.
bool _print_assembly; // True if we should dump assembly code for this compilation bool _print_assembly; // True if we should dump assembly code for this compilation
bool _print_inlining; // True if we should print inlining for this compilation
bool _print_intrinsics; // True if we should print intrinsics for this compilation
#ifndef PRODUCT #ifndef PRODUCT
bool _trace_opto_output; bool _trace_opto_output;
bool _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing bool _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing
@ -414,7 +416,7 @@ class Compile : public Phase {
}; };
GrowableArray<PrintInliningBuffer>* _print_inlining_list; GrowableArray<PrintInliningBuffer>* _print_inlining_list;
int _print_inlining; int _print_inlining_idx;
// Only keep nodes in the expensive node list that need to be optimized // Only keep nodes in the expensive node list that need to be optimized
void cleanup_expensive_nodes(PhaseIterGVN &igvn); void cleanup_expensive_nodes(PhaseIterGVN &igvn);
@ -426,24 +428,24 @@ class Compile : public Phase {
public: public:
outputStream* print_inlining_stream() const { outputStream* print_inlining_stream() const {
return _print_inlining_list->at(_print_inlining).ss(); return _print_inlining_list->adr_at(_print_inlining_idx)->ss();
} }
void print_inlining_skip(CallGenerator* cg) { void print_inlining_skip(CallGenerator* cg) {
if (PrintInlining) { if (_print_inlining) {
_print_inlining_list->at(_print_inlining).set_cg(cg); _print_inlining_list->adr_at(_print_inlining_idx)->set_cg(cg);
_print_inlining++; _print_inlining_idx++;
_print_inlining_list->insert_before(_print_inlining, PrintInliningBuffer()); _print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer());
} }
} }
void print_inlining_insert(CallGenerator* cg) { void print_inlining_insert(CallGenerator* cg) {
if (PrintInlining) { if (_print_inlining) {
for (int i = 0; i < _print_inlining_list->length(); i++) { for (int i = 0; i < _print_inlining_list->length(); i++) {
if (_print_inlining_list->at(i).cg() == cg) { if (_print_inlining_list->adr_at(i)->cg() == cg) {
_print_inlining_list->insert_before(i+1, PrintInliningBuffer()); _print_inlining_list->insert_before(i+1, PrintInliningBuffer());
_print_inlining = i+1; _print_inlining_idx = i+1;
_print_inlining_list->at(i).set_cg(NULL); _print_inlining_list->adr_at(i)->set_cg(NULL);
return; return;
} }
} }
@ -572,6 +574,10 @@ class Compile : public Phase {
int AliasLevel() const { return _AliasLevel; } int AliasLevel() const { return _AliasLevel; }
bool print_assembly() const { return _print_assembly; } bool print_assembly() const { return _print_assembly; }
void set_print_assembly(bool z) { _print_assembly = z; } void set_print_assembly(bool z) { _print_assembly = z; }
bool print_inlining() const { return _print_inlining; }
void set_print_inlining(bool z) { _print_inlining = z; }
bool print_intrinsics() const { return _print_intrinsics; }
void set_print_intrinsics(bool z) { _print_intrinsics = z; }
// check the CompilerOracle for special behaviours for this compile // check the CompilerOracle for special behaviours for this compile
bool method_has_option(const char * option) { bool method_has_option(const char * option) {
return method() != NULL && method()->has_option(option); return method() != NULL && method()->has_option(option);

View File

@ -41,9 +41,9 @@
#include "runtime/sharedRuntime.hpp" #include "runtime/sharedRuntime.hpp"
void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) { void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) {
if (TraceTypeProfile || PrintInlining NOT_PRODUCT(|| PrintOptoInlining)) { if (TraceTypeProfile || C->print_inlining()) {
outputStream* out = tty; outputStream* out = tty;
if (!PrintInlining) { if (!C->print_inlining()) {
if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) { if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) {
method->print_short_name(); method->print_short_name();
tty->cr(); tty->cr();

View File

@ -543,7 +543,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
Compile* C = kit.C; Compile* C = kit.C;
int nodes = C->unique(); int nodes = C->unique();
#ifndef PRODUCT #ifndef PRODUCT
if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) { if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
char buf[1000]; char buf[1000];
const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
tty->print_cr("Intrinsic %s", str); tty->print_cr("Intrinsic %s", str);
@ -554,7 +554,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
// Try to inline the intrinsic. // Try to inline the intrinsic.
if (kit.try_to_inline()) { if (kit.try_to_inline()) {
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { if (C->print_intrinsics() || C->print_inlining()) {
C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
} }
C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
@ -570,7 +570,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
} }
// The intrinsic bailed out // The intrinsic bailed out
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { if (C->print_intrinsics() || C->print_inlining()) {
if (jvms->has_method()) { if (jvms->has_method()) {
// Not a root compile. // Not a root compile.
const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)"; const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
@ -592,7 +592,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) {
int nodes = C->unique(); int nodes = C->unique();
#ifndef PRODUCT #ifndef PRODUCT
assert(is_predicted(), "sanity"); assert(is_predicted(), "sanity");
if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) { if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
char buf[1000]; char buf[1000];
const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
tty->print_cr("Predicate for intrinsic %s", str); tty->print_cr("Predicate for intrinsic %s", str);
@ -603,7 +603,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) {
Node* slow_ctl = kit.try_to_predicate(); Node* slow_ctl = kit.try_to_predicate();
if (!kit.failing()) { if (!kit.failing()) {
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { if (C->print_intrinsics() || C->print_inlining()) {
C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
} }
C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
@ -617,7 +617,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) {
} }
// The intrinsic bailed out // The intrinsic bailed out
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { if (C->print_intrinsics() || C->print_inlining()) {
if (jvms->has_method()) { if (jvms->has_method()) {
// Not a root compile. // Not a root compile.
const char* msg = "failed to generate predicate for intrinsic"; const char* msg = "failed to generate predicate for intrinsic";
@ -2299,7 +2299,7 @@ const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_
const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass); const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass);
#ifndef PRODUCT #ifndef PRODUCT
if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { if (C->print_intrinsics() || C->print_inlining()) {
tty->print(" from base type: "); adr_type->dump(); tty->print(" from base type: "); adr_type->dump();
tty->print(" sharpened value: "); tjp->dump(); tty->print(" sharpened value: "); tjp->dump();
} }
@ -3260,7 +3260,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) {
if (mirror_con == NULL) return false; // cannot happen? if (mirror_con == NULL) return false; // cannot happen?
#ifndef PRODUCT #ifndef PRODUCT
if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { if (C->print_intrinsics() || C->print_inlining()) {
ciType* k = mirror_con->java_mirror_type(); ciType* k = mirror_con->java_mirror_type();
if (k) { if (k) {
tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id())); tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id()));
@ -3952,14 +3952,14 @@ bool LibraryCallKit::inline_native_getClass() {
// caller sensitive methods. // caller sensitive methods.
bool LibraryCallKit::inline_native_Reflection_getCallerClass() { bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
#ifndef PRODUCT #ifndef PRODUCT
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass"); tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass");
} }
#endif #endif
if (!jvms()->has_method()) { if (!jvms()->has_method()) {
#ifndef PRODUCT #ifndef PRODUCT
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
tty->print_cr(" Bailing out because intrinsic was inlined at top level"); tty->print_cr(" Bailing out because intrinsic was inlined at top level");
} }
#endif #endif
@ -3983,7 +3983,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
// Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass). // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass).
if (!m->caller_sensitive()) { if (!m->caller_sensitive()) {
#ifndef PRODUCT #ifndef PRODUCT
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
tty->print_cr(" Bailing out: CallerSensitive annotation expected at frame %d", n); tty->print_cr(" Bailing out: CallerSensitive annotation expected at frame %d", n);
} }
#endif #endif
@ -3999,7 +3999,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
set_result(makecon(TypeInstPtr::make(caller_mirror))); set_result(makecon(TypeInstPtr::make(caller_mirror)));
#ifndef PRODUCT #ifndef PRODUCT
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
tty->print_cr(" Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth()); tty->print_cr(" Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth());
tty->print_cr(" JVM state at this point:"); tty->print_cr(" JVM state at this point:");
for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {
@ -4015,7 +4015,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
} }
#ifndef PRODUCT #ifndef PRODUCT
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth()); tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth());
tty->print_cr(" JVM state at this point:"); tty->print_cr(" JVM state at this point:");
for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {

View File

@ -5046,7 +5046,10 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
void TestReservedSpace_test(); void TestReservedSpace_test();
void TestReserveMemorySpecial_test(); void TestReserveMemorySpecial_test();
void TestVirtualSpace_test(); void TestVirtualSpace_test();
void MetaspaceAux_test(); void TestMetaspaceAux_test();
#if INCLUDE_ALL_GCS
void TestG1BiasedArray_test();
#endif
void execute_internal_vm_tests() { void execute_internal_vm_tests() {
if (ExecuteInternalVMTests) { if (ExecuteInternalVMTests) {
@ -5054,7 +5057,7 @@ void execute_internal_vm_tests() {
run_unit_test(TestReservedSpace_test()); run_unit_test(TestReservedSpace_test());
run_unit_test(TestReserveMemorySpecial_test()); run_unit_test(TestReserveMemorySpecial_test());
run_unit_test(TestVirtualSpace_test()); run_unit_test(TestVirtualSpace_test());
run_unit_test(MetaspaceAux_test()); run_unit_test(TestMetaspaceAux_test());
run_unit_test(GlobalDefinitions::test_globals()); run_unit_test(GlobalDefinitions::test_globals());
run_unit_test(GCTimerAllTest::all()); run_unit_test(GCTimerAllTest::all());
run_unit_test(arrayOopDesc::test_max_array_length()); run_unit_test(arrayOopDesc::test_max_array_length());
@ -5066,6 +5069,7 @@ void execute_internal_vm_tests() {
run_unit_test(VMStructs::test()); run_unit_test(VMStructs::test());
#endif #endif
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
run_unit_test(TestG1BiasedArray_test());
run_unit_test(HeapRegionRemSet::test_prt()); run_unit_test(HeapRegionRemSet::test_prt());
#endif #endif
tty->print_cr("All internal VM tests passed"); tty->print_cr("All internal VM tests passed");

View File

@ -1835,16 +1835,27 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass,
} }
JVM_END JVM_END
JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) static bool select_method(methodHandle method, bool want_constructor) {
{ if (want_constructor) {
JVMWrapper("JVM_GetClassDeclaredMethods"); return (method->is_initializer() && !method->is_static());
} else {
return (!method->is_initializer() && !method->is_overpass());
}
}
static jobjectArray get_class_declared_methods_helper(
JNIEnv *env,
jclass ofClass, jboolean publicOnly,
bool want_constructor,
Klass* klass, TRAPS) {
JvmtiVMObjectAllocEventCollector oam; JvmtiVMObjectAllocEventCollector oam;
// Exclude primitive types and array types // Exclude primitive types and array types
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass))
|| java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {
// Return empty array // Return empty array
oop res = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), 0, CHECK_NULL); oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL);
return (jobjectArray) JNIHandles::make_local(env, res); return (jobjectArray) JNIHandles::make_local(env, res);
} }
@ -1855,87 +1866,67 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass,
Array<Method*>* methods = k->methods(); Array<Method*>* methods = k->methods();
int methods_length = methods->length(); int methods_length = methods->length();
// Save original method_idnum in case of redefinition, which can change
// the idnum of obsolete methods. The new method will have the same idnum
// but if we refresh the methods array, the counts will be wrong.
ResourceMark rm(THREAD);
GrowableArray<int>* idnums = new GrowableArray<int>(methods_length);
int num_methods = 0; int num_methods = 0;
int i; for (int i = 0; i < methods_length; i++) {
for (i = 0; i < methods_length; i++) {
methodHandle method(THREAD, methods->at(i)); methodHandle method(THREAD, methods->at(i));
if (!method->is_initializer() && !method->is_overpass()) { if (select_method(method, want_constructor)) {
if (!publicOnly || method->is_public()) { if (!publicOnly || method->is_public()) {
idnums->push(method->method_idnum());
++num_methods; ++num_methods;
} }
} }
} }
// Allocate result // Allocate result
objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), num_methods, CHECK_NULL); objArrayOop r = oopFactory::new_objArray(klass, num_methods, CHECK_NULL);
objArrayHandle result (THREAD, r); objArrayHandle result (THREAD, r);
int out_idx = 0; // Now just put the methods that we selected above, but go by their idnum
for (i = 0; i < methods_length; i++) { // in case of redefinition. The methods can be redefined at any safepoint,
methodHandle method(THREAD, methods->at(i)); // so above when allocating the oop array and below when creating reflect
if (!method->is_initializer() && !method->is_overpass()) { // objects.
if (!publicOnly || method->is_public()) { for (int i = 0; i < num_methods; i++) {
oop m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); methodHandle method(THREAD, k->method_with_idnum(idnums->at(i)));
result->obj_at_put(out_idx, m); if (method.is_null()) {
++out_idx; // Method may have been deleted and seems this API can handle null
// Otherwise should probably put a method that throws NSME
result->obj_at_put(i, NULL);
} else {
oop m;
if (want_constructor) {
m = Reflection::new_constructor(method, CHECK_NULL);
} else {
m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL);
} }
result->obj_at_put(i, m);
} }
} }
assert(out_idx == num_methods, "just checking");
return (jobjectArray) JNIHandles::make_local(env, result()); return (jobjectArray) JNIHandles::make_local(env, result());
} }
JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly))
{
JVMWrapper("JVM_GetClassDeclaredMethods");
return get_class_declared_methods_helper(env, ofClass, publicOnly,
/*want_constructor*/ false,
SystemDictionary::reflect_Method_klass(), THREAD);
}
JVM_END JVM_END
JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)) JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly))
{ {
JVMWrapper("JVM_GetClassDeclaredConstructors"); JVMWrapper("JVM_GetClassDeclaredConstructors");
JvmtiVMObjectAllocEventCollector oam; return get_class_declared_methods_helper(env, ofClass, publicOnly,
/*want_constructor*/ true,
// Exclude primitive types and array types SystemDictionary::reflect_Constructor_klass(), THREAD);
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass))
|| java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {
// Return empty array
oop res = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0 , CHECK_NULL);
return (jobjectArray) JNIHandles::make_local(env, res);
}
instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));
// Ensure class is linked
k->link_class(CHECK_NULL);
Array<Method*>* methods = k->methods();
int methods_length = methods->length();
int num_constructors = 0;
int i;
for (i = 0; i < methods_length; i++) {
methodHandle method(THREAD, methods->at(i));
if (method->is_initializer() && !method->is_static()) {
if (!publicOnly || method->is_public()) {
++num_constructors;
}
}
}
// Allocate result
objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), num_constructors, CHECK_NULL);
objArrayHandle result(THREAD, r);
int out_idx = 0;
for (i = 0; i < methods_length; i++) {
methodHandle method(THREAD, methods->at(i));
if (method->is_initializer() && !method->is_static()) {
if (!publicOnly || method->is_public()) {
oop m = Reflection::new_constructor(method, CHECK_NULL);
result->obj_at_put(out_idx, m);
++out_idx;
}
}
}
assert(out_idx == num_constructors, "just checking");
return (jobjectArray) JNIHandles::make_local(env, result());
} }
JVM_END JVM_END

View File

@ -406,7 +406,11 @@ public:
VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; } VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; }
jvmtiError result() { return _result; } jvmtiError result() { return _result; }
void doit() { void doit() {
_result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
if (Threads::includes(_java_thread) && !_java_thread->is_exiting() &&
_java_thread->threadObj() != NULL) {
_result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);
}
} }
}; };

View File

@ -273,59 +273,49 @@ void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
// add/remove breakpoint to/from versions of the method that // add/remove breakpoint to/from versions of the method that
// are EMCP. Directly or transitively obsolete methods are // are EMCP. Directly or transitively obsolete methods are
// not saved in the PreviousVersionInfo. // not saved in the PreviousVersionNodes.
Thread *thread = Thread::current(); Thread *thread = Thread::current();
instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());
Symbol* m_name = _method->name(); Symbol* m_name = _method->name();
Symbol* m_signature = _method->signature(); Symbol* m_signature = _method->signature();
{ // search previous versions if they exist
ResourceMark rm(thread); PreviousVersionWalker pvw(thread, (InstanceKlass *)ikh());
// PreviousVersionInfo objects returned via PreviousVersionWalker for (PreviousVersionNode * pv_node = pvw.next_previous_version();
// contain a GrowableArray of handles. We have to clean up the pv_node != NULL; pv_node = pvw.next_previous_version()) {
// GrowableArray _after_ the PreviousVersionWalker destructor GrowableArray<Method*>* methods = pv_node->prev_EMCP_methods();
// has destroyed the handles.
{
// search previous versions if they exist
PreviousVersionWalker pvw((InstanceKlass *)ikh());
for (PreviousVersionInfo * pv_info = pvw.next_previous_version();
pv_info != NULL; pv_info = pvw.next_previous_version()) {
GrowableArray<methodHandle>* methods =
pv_info->prev_EMCP_method_handles();
if (methods == NULL) { if (methods == NULL) {
// We have run into a PreviousVersion generation where // We have run into a PreviousVersion generation where
// all methods were made obsolete during that generation's // all methods were made obsolete during that generation's
// RedefineClasses() operation. At the time of that // RedefineClasses() operation. At the time of that
// operation, all EMCP methods were flushed so we don't // operation, all EMCP methods were flushed so we don't
// have to go back any further. // have to go back any further.
// //
// A NULL methods array is different than an empty methods // A NULL methods array is different than an empty methods
// array. We cannot infer any optimizations about older // array. We cannot infer any optimizations about older
// generations from an empty methods array for the current // generations from an empty methods array for the current
// generation. // generation.
break; break;
} }
for (int i = methods->length() - 1; i >= 0; i--) { for (int i = methods->length() - 1; i >= 0; i--) {
methodHandle method = methods->at(i); Method* method = methods->at(i);
// obsolete methods that are running are not deleted from // obsolete methods that are running are not deleted from
// previous version array, but they are skipped here. // previous version array, but they are skipped here.
if (!method->is_obsolete() && if (!method->is_obsolete() &&
method->name() == m_name && method->name() == m_name &&
method->signature() == m_signature) { method->signature() == m_signature) {
RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
meth_act == &Method::set_breakpoint ? "sett" : "clear", meth_act == &Method::set_breakpoint ? "sett" : "clear",
method->name()->as_C_string(), method->name()->as_C_string(),
method->signature()->as_C_string())); method->signature()->as_C_string()));
((Method*)method()->*meth_act)(_bci); (method->*meth_act)(_bci);
break; break;
}
}
} }
} // pvw is cleaned up }
} // rm is cleaned up }
} }
void JvmtiBreakpoint::set() { void JvmtiBreakpoint::set() {

View File

@ -2807,28 +2807,20 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
&trace_name_printed); &trace_name_printed);
} }
} }
{
ResourceMark rm(_thread); // the previous versions' constant pool caches may need adjustment
// PreviousVersionInfo objects returned via PreviousVersionWalker PreviousVersionWalker pvw(_thread, ik);
// contain a GrowableArray of handles. We have to clean up the for (PreviousVersionNode * pv_node = pvw.next_previous_version();
// GrowableArray _after_ the PreviousVersionWalker destructor pv_node != NULL; pv_node = pvw.next_previous_version()) {
// has destroyed the handles. other_cp = pv_node->prev_constant_pool();
{ cp_cache = other_cp->cache();
// the previous versions' constant pool caches may need adjustment if (cp_cache != NULL) {
PreviousVersionWalker pvw(ik); cp_cache->adjust_method_entries(_matching_old_methods,
for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); _matching_new_methods,
pv_info != NULL; pv_info = pvw.next_previous_version()) { _matching_methods_length,
other_cp = pv_info->prev_constant_pool_handle(); &trace_name_printed);
cp_cache = other_cp->cache(); }
if (cp_cache != NULL) { }
cp_cache->adjust_method_entries(_matching_old_methods,
_matching_new_methods,
_matching_methods_length,
&trace_name_printed);
}
}
} // pvw is cleaned up
} // rm is cleaned up
} }
} }
@ -2942,10 +2934,9 @@ void VM_RedefineClasses::check_methods_and_mark_as_obsolete(
// obsolete methods need a unique idnum // obsolete methods need a unique idnum
u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum(); u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum();
if (num != ConstMethod::UNSET_IDNUM) { if (num != ConstMethod::UNSET_IDNUM) {
// u2 old_num = old_method->method_idnum();
old_method->set_method_idnum(num); old_method->set_method_idnum(num);
// TO DO: attach obsolete annotations to obsolete method's new idnum
} }
// With tracing we try not to "yack" too much. The position of // With tracing we try not to "yack" too much. The position of
// this trace assumes there are fewer obsolete methods than // this trace assumes there are fewer obsolete methods than
// EMCP methods. // EMCP methods.

View File

@ -1100,6 +1100,7 @@ void Arguments::set_mode_flags(Mode mode) {
} }
} }
#if defined(COMPILER2) || defined(_LP64) || !INCLUDE_CDS
// Conflict: required to use shared spaces (-Xshare:on), but // Conflict: required to use shared spaces (-Xshare:on), but
// incompatible command line options were chosen. // incompatible command line options were chosen.
@ -1112,6 +1113,7 @@ static void no_shared_spaces() {
FLAG_SET_DEFAULT(UseSharedSpaces, false); FLAG_SET_DEFAULT(UseSharedSpaces, false);
} }
} }
#endif
void Arguments::set_tiered_flags() { void Arguments::set_tiered_flags() {
// With tiered, set default policy to AdvancedThresholdPolicy, which is 3. // With tiered, set default policy to AdvancedThresholdPolicy, which is 3.
@ -1520,16 +1522,18 @@ void Arguments::set_ergonomics_flags() {
FLAG_SET_ERGO(bool, UseParallelGC, true); FLAG_SET_ERGO(bool, UseParallelGC, true);
} }
} }
// Shared spaces work fine with other GCs but causes bytecode rewriting
// to be disabled, which hurts interpreter performance and decreases
// server performance. On server class machines, keep the default
// off unless it is asked for. Future work: either add bytecode rewriting
// at link time, or rewrite bytecodes in non-shared methods.
if (!DumpSharedSpaces && !RequireSharedSpaces &&
(FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) {
no_shared_spaces();
}
} }
#ifdef COMPILER2
// Shared spaces work fine with other GCs but causes bytecode rewriting
// to be disabled, which hurts interpreter performance and decreases
// server performance. When -server is specified, keep the default off
// unless it is asked for. Future work: either add bytecode rewriting
// at link time, or rewrite bytecodes in non-shared methods.
if (!DumpSharedSpaces && !RequireSharedSpaces &&
(FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) {
no_shared_spaces();
}
#endif
set_conservative_max_heap_alignment(); set_conservative_max_heap_alignment();
@ -2439,21 +2443,6 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) {
return result; return result;
} }
if (AggressiveOpts) {
// Insert alt-rt.jar between user-specified bootclasspath
// prefix and the default bootclasspath. os::set_boot_path()
// uses meta_index_dir as the default bootclasspath directory.
const char* altclasses_jar = "alt-rt.jar";
size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 +
strlen(altclasses_jar);
char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len, mtInternal);
strcpy(altclasses_path, get_meta_index_dir());
strcat(altclasses_path, altclasses_jar);
scp.add_suffix_to_prefix(altclasses_path);
scp_assembly_required = true;
FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal);
}
// Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM)
result = parse_java_options_environment_variable(&scp, &scp_assembly_required); result = parse_java_options_environment_variable(&scp, &scp_assembly_required);
if (result != JNI_OK) { if (result != JNI_OK) {

View File

@ -2526,6 +2526,9 @@ class CommandLineFlags {
product(bool, PrintStringTableStatistics, false, \ product(bool, PrintStringTableStatistics, false, \
"print statistics about the StringTable and SymbolTable") \ "print statistics about the StringTable and SymbolTable") \
\ \
diagnostic(bool, VerifyStringTableAtExit, false, \
"verify StringTable contents at exit") \
\
notproduct(bool, PrintSymbolTableSizeHistogram, false, \ notproduct(bool, PrintSymbolTableSizeHistogram, false, \
"print histogram of the symbol table") \ "print histogram of the symbol table") \
\ \

View File

@ -136,7 +136,7 @@ DEF_HANDLE(typeArray , is_typeArray )
// Specific Handles for different oop types // Specific Handles for different oop types
#define DEF_METADATA_HANDLE(name, type) \ #define DEF_METADATA_HANDLE(name, type) \
class name##Handle; \ class name##Handle; \
class name##Handle { \ class name##Handle : public StackObj { \
type* _value; \ type* _value; \
Thread* _thread; \ Thread* _thread; \
protected: \ protected: \
@ -175,7 +175,7 @@ DEF_METADATA_HANDLE(constantPool, ConstantPool)
// Writing this class explicitly, since DEF_METADATA_HANDLE(klass) doesn't // Writing this class explicitly, since DEF_METADATA_HANDLE(klass) doesn't
// provide the necessary Klass* <-> Klass* conversions. This Klass // provide the necessary Klass* <-> Klass* conversions. This Klass
// could be removed when we don't have the Klass* typedef anymore. // could be removed when we don't have the Klass* typedef anymore.
class KlassHandle { class KlassHandle : public StackObj {
Klass* _value; Klass* _value;
protected: protected:
Klass* obj() const { return _value; } Klass* obj() const { return _value; }

View File

@ -79,6 +79,7 @@ inline name##Handle::name##Handle(const name##Handle &h) { \
} else { \ } else { \
_thread = Thread::current(); \ _thread = Thread::current(); \
} \ } \
assert (_thread->is_in_stack((address)this), "not on stack?"); \
_thread->metadata_handles()->push((Metadata*)_value); \ _thread->metadata_handles()->push((Metadata*)_value); \
} else { \ } else { \
_thread = NULL; \ _thread = NULL; \
@ -95,6 +96,7 @@ inline name##Handle& name##Handle::operator=(const name##Handle &s) { \
} else { \ } else { \
_thread = Thread::current(); \ _thread = Thread::current(); \
} \ } \
assert (_thread->is_in_stack((address)this), "not on stack?"); \
_thread->metadata_handles()->push((Metadata*)_value); \ _thread->metadata_handles()->push((Metadata*)_value); \
} else { \ } else { \
_thread = NULL; \ _thread = NULL; \

View File

@ -544,6 +544,19 @@ void before_exit(JavaThread * thread) {
// it will run into trouble when system destroys static variables. // it will run into trouble when system destroys static variables.
MemTracker::shutdown(MemTracker::NMT_normal); MemTracker::shutdown(MemTracker::NMT_normal);
if (VerifyStringTableAtExit) {
int fail_cnt = 0;
{
MutexLocker ml(StringTable_lock);
fail_cnt = StringTable::verify_and_compare_entries();
}
if (fail_cnt != 0) {
tty->print_cr("ERROR: fail_cnt=%d", fail_cnt);
guarantee(fail_cnt == 0, "unexpected StringTable verification failures");
}
}
#undef BEFORE_EXIT_NOT_RUN #undef BEFORE_EXIT_NOT_RUN
#undef BEFORE_EXIT_RUNNING #undef BEFORE_EXIT_RUNNING
#undef BEFORE_EXIT_DONE #undef BEFORE_EXIT_DONE

View File

@ -1506,8 +1506,11 @@ methodHandle SharedRuntime::handle_ic_miss_helper(JavaThread *thread, TRAPS) {
info, CHECK_(methodHandle())); info, CHECK_(methodHandle()));
inline_cache->set_to_monomorphic(info); inline_cache->set_to_monomorphic(info);
} else if (!inline_cache->is_megamorphic() && !inline_cache->is_clean()) { } else if (!inline_cache->is_megamorphic() && !inline_cache->is_clean()) {
// Change to megamorphic // Potential change to megamorphic
inline_cache->set_to_megamorphic(&call_info, bc, CHECK_(methodHandle())); bool successful = inline_cache->set_to_megamorphic(&call_info, bc, CHECK_(methodHandle()));
if (!successful) {
inline_cache->set_to_clean();
}
} else { } else {
// Either clean or megamorphic // Either clean or megamorphic
} }

View File

@ -78,7 +78,13 @@ class Abstract_VM_Version: AllStatic {
static const char* jre_release_version(); static const char* jre_release_version();
// does HW support an 8-byte compare-exchange operation? // does HW support an 8-byte compare-exchange operation?
static bool supports_cx8() {return _supports_cx8;} static bool supports_cx8() {
#ifdef SUPPORTS_NATIVE_CX8
return true;
#else
return _supports_cx8;
#endif
}
// does HW support atomic get-and-set or atomic get-and-add? Used // does HW support atomic get-and-set or atomic get-and-add? Used
// to guide intrinsification decisions for Unsafe atomic ops // to guide intrinsification decisions for Unsafe atomic ops
static bool supports_atomic_getset4() {return _supports_atomic_getset4;} static bool supports_atomic_getset4() {return _supports_atomic_getset4;}

View File

@ -470,7 +470,17 @@ void AttachListener::init() {
vmSymbols::threadgroup_string_void_signature(), vmSymbols::threadgroup_string_void_signature(),
thread_group, thread_group,
string, string,
CHECK); THREAD);
if (HAS_PENDING_EXCEPTION) {
tty->print_cr("Exception in VM (AttachListener::init) : ");
java_lang_Throwable::print(PENDING_EXCEPTION, tty);
tty->cr();
CLEAR_PENDING_EXCEPTION;
return;
}
KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass()); KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass());
JavaCalls::call_special(&result, JavaCalls::call_special(&result,
@ -479,7 +489,17 @@ void AttachListener::init() {
vmSymbols::add_method_name(), vmSymbols::add_method_name(),
vmSymbols::thread_void_signature(), vmSymbols::thread_void_signature(),
thread_oop, // ARG 1 thread_oop, // ARG 1
CHECK); THREAD);
if (HAS_PENDING_EXCEPTION) {
tty->print_cr("Exception in VM (AttachListener::init) : ");
java_lang_Throwable::print(PENDING_EXCEPTION, tty);
tty->cr();
CLEAR_PENDING_EXCEPTION;
return;
}
{ MutexLocker mu(Threads_lock); { MutexLocker mu(Threads_lock);
JavaThread* listener_thread = new JavaThread(&attach_listener_thread_entry); JavaThread* listener_thread = new JavaThread(&attach_listener_thread_entry);

View File

@ -61,7 +61,7 @@ void GenDCmdArgument::to_string(MemorySizeArgument m, char* buf, size_t len) {
} }
void GenDCmdArgument::to_string(char* c, char* buf, size_t len) { void GenDCmdArgument::to_string(char* c, char* buf, size_t len) {
jio_snprintf(buf, len, "%s", c); jio_snprintf(buf, len, "%s", (c != NULL) ? c : "");
} }
void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) { void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) {

View File

@ -1,12 +1,10 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this * published by the Free Software Foundation.
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -23,12 +21,16 @@
* questions. * questions.
*/ */
package sun.lwawt;
/* /*
* Every time the TextField (or TextArea) change selection, every other text components * @test
* must immediately clear their selections. * @bug 8022585
* @summary VM crashes when ran with -XX:+PrintInlining
* @run main/othervm -Xcomp -XX:+PrintInlining PrintInlining
*
*/ */
interface SelectionClearListener {
void clearSelection(); public class PrintInlining {
public static void main(String[] args) {
System.out.println("Passed");
}
} }

View File

@ -33,16 +33,9 @@ import com.oracle.java.testlibrary.*;
public class XShareAuto { public class XShareAuto {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if (!Platform.is64bit()) {
System.out.println("ObjectAlignmentInBytes for CDS is only " +
"supported on 64bit platforms; this plaform is " +
System.getProperty("sun.arch.data.model"));
System.out.println("Skipping the test");
return;
}
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-server", "-XX:+UnlockDiagnosticVMOptions",
"-Xshare:dump"); "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Loading classes to share"); output.shouldContain("Loading classes to share");
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);

View File

@ -230,3 +230,4 @@ a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104
d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106 d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106
d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107 d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107
8ade3eed63da87067a7137c111f684a821e9e531 jdk8-b108 8ade3eed63da87067a7137c111f684a821e9e531 jdk8-b108
02bfab2aa93899e0f02584f1e85537485a196553 jdk8-b109

View File

@ -230,3 +230,4 @@ b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98
6908370afe834ff01739e8ec992d4246c74b7e6e jdk8-b106 6908370afe834ff01739e8ec992d4246c74b7e6e jdk8-b106
e3c9328f75638289a342ce15fbe532f05078946e jdk8-b107 e3c9328f75638289a342ce15fbe532f05078946e jdk8-b107
d1ea68556fd7925a3c7078dd9f77c6ca73d5aa9e jdk8-b108 d1ea68556fd7925a3c7078dd9f77c6ca73d5aa9e jdk8-b108
df5d4d01642572e77fd3c01e4c8703ed3f6eec87 jdk8-b109

View File

@ -230,3 +230,4 @@ f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104
c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106 c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106
eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107 eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107
006aaa5f069e7dd98fccdc696866c9f8582c087c jdk8-b108 006aaa5f069e7dd98fccdc696866c9f8582c087c jdk8-b108
946f3fd5f8bf0ccd180c258d25e5837fa1bf004c jdk8-b109

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -51,7 +51,7 @@ endif
# #
# Java files to compile. # Java files to compile.
# #
FILES_java = com/sun/java/accessibility/AccessBridge.java FILES_java = com/sun/java/accessibility/AccessBridgeLoader.java com/sun/java/accessibility/AccessBridge.java
# #
# Location for the newly built classfiles. # Location for the newly built classfiles.
@ -61,14 +61,13 @@ CLASSDESTDIR = $(TEMPDIR)/classes
# #
# Rules # Rules
# #
CLASSDESTDIR = $(TEMPDIR)/classes
FILES_class = $(FILES_java:%.java=$(CLASSDESTDIR)/%.class) FILES_class = $(FILES_java:%.java=$(CLASSDESTDIR)/%.class)
build: prebuild build: prebuild
prebuild: prebuild:
$(CP) $(CLOSED_PLATFORM_SRC)/classes/com/sun/java/accessibility/$(ABPLATFORM)/AccessBridge.java \ $(CP) $(CLOSED_PLATFORM_SRC)/classes/com/sun/java/accessibility/$(ABPLATFORM)/AccessBridgeLoader.java \
$(CLOSED_PLATFORM_SRC)/classes/com/sun/java/accessibility $(CLOSED_PLATFORM_SRC)/classes/com/sun/java/accessibility
all : build $(JARFILE) all : build $(JARFILE)

View File

@ -70,9 +70,13 @@ POLICY_BUILD = $(LIBDIR)/security/java.policy
CACERTS_SRC = $(CACERTS_FILE) CACERTS_SRC = $(CACERTS_FILE)
CACERTS_BUILD = $(LIBDIR)/security/cacerts CACERTS_BUILD = $(LIBDIR)/security/cacerts
BLACKLISTED_CERTS_SRC = $(TOPDIR)/src/share/lib/security/blacklisted.certs
BLACKLISTED_CERTS_BUILD = $(LIBDIR)/security/blacklisted.certs
ifndef OPENJDK ifndef OPENJDK
BLACKLIST_SRC = $(CLOSED_SHARE_SRC)/lib/security/blacklist BLACKLIST_SRC = $(CLOSED_SHARE_SRC)/lib/security/blacklist
BLACKLIST_BUILD = $(LIBDIR)/security/blacklist BLACKLIST_BUILD = $(LIBDIR)/security/blacklist
BLACKLISTED_CERTS_SRC += $(wildcard $(CLOSED_SHARE_SRC)/lib/security/blacklisted.certs)
TRUSTEDLIBS_SRC = $(CLOSED_SHARE_SRC)/lib/security/trusted.libraries TRUSTEDLIBS_SRC = $(CLOSED_SHARE_SRC)/lib/security/trusted.libraries
TRUSTEDLIBS_BUILD = $(LIBDIR)/security/trusted.libraries TRUSTEDLIBS_BUILD = $(LIBDIR)/security/trusted.libraries
endif endif
@ -85,9 +89,9 @@ FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class)
include $(BUILDDIR)/common/Rules.gmk include $(BUILDDIR)/common/Rules.gmk
ifdef OPENJDK ifdef OPENJDK
build: properties policy cacerts build: properties policy cacerts blacklisted-certs
else else
build: properties policy cacerts blacklist trustedlibs build: properties policy cacerts blacklist blacklisted-certs trustedlibs
endif endif
install: all install: all
@ -100,6 +104,8 @@ cacerts: classes $(CACERTS_BUILD)
blacklist: classes $(BLACKLIST_BUILD) blacklist: classes $(BLACKLIST_BUILD)
blacklisted-certs: classes $(BLACKLISTED_CERTS_BUILD)
trustedlibs: classes $(TRUSTEDLIBS_BUILD) trustedlibs: classes $(TRUSTEDLIBS_BUILD)
$(PROPS_BUILD): $(PROPS_SRC) $(PROPS_BUILD): $(PROPS_SRC)
@ -114,12 +120,25 @@ $(CACERTS_BUILD): $(CACERTS_SRC)
$(BLACKLIST_BUILD): $(BLACKLIST_SRC) $(BLACKLIST_BUILD): $(BLACKLIST_SRC)
$(install-file) $(install-file)
$(BLACKLISTED_CERTS_BUILD): $(BLACKLISTED_CERTS_SRC)
$(MKDIR) -p $(@D)
$(CAT) $^ | $(SED) '/^$$/d' | $(SORT) | $(UNIQ) > $@.tmp
$(GREP) -i Algorithm $@.tmp > $@
if [ `$(SED) -n -e "$$=" $@` != 1 ]; then \
$(ECHO) "Different algorithms defined in $^"; \
$(RM) $@ $@.tmp; \
false; \
fi
$(GREP) -iv Algorithm $@.tmp >> $@
$(RM) $@.tmp
$(TRUSTEDLIBS_BUILD): $(TRUSTEDLIBS_SRC) $(TRUSTEDLIBS_BUILD): $(TRUSTEDLIBS_SRC)
$(install-file) $(install-file)
clean clobber:: .delete.classlist clean clobber:: .delete.classlist
$(RM) -r $(CLASSBINDIR)/java/security $(RM) -r $(CLASSBINDIR)/java/security
$(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD) $(TRUSTEDLIBS_BUILD) $(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD) \
$(BLACKLISTED_CERTS_BUILD) $(TRUSTEDLIBS_BUILD)
# Additional Rule for building sun.security.util # Additional Rule for building sun.security.util
$(CLASSBINDIR)/%.class: $(SHARE_SRC)/sun/%.java $(CLASSBINDIR)/%.class: $(SHARE_SRC)/sun/%.java

View File

@ -110,7 +110,6 @@ FILES_export = \
sun/lwawt/LWWindowPeer.java \ sun/lwawt/LWWindowPeer.java \
sun/lwawt/PlatformWindow.java \ sun/lwawt/PlatformWindow.java \
sun/lwawt/SecurityWarningWindow.java \ sun/lwawt/SecurityWarningWindow.java \
sun/lwawt/SelectionClearListener.java \
sun/lwawt/macosx/CPrinterDevice.java \ sun/lwawt/macosx/CPrinterDevice.java \
sun/lwawt/macosx/CPrinterDialog.java \ sun/lwawt/macosx/CPrinterDialog.java \
sun/lwawt/macosx/CPrinterDialogPeer.java \ sun/lwawt/macosx/CPrinterDialogPeer.java \
@ -141,7 +140,6 @@ FILES_export = \
sun/lwawt/macosx/CMenuBar.java \ sun/lwawt/macosx/CMenuBar.java \
sun/lwawt/macosx/CMenuComponent.java \ sun/lwawt/macosx/CMenuComponent.java \
sun/lwawt/macosx/CMenuItem.java \ sun/lwawt/macosx/CMenuItem.java \
sun/lwawt/macosx/CMouseInfoPeer.java \
sun/lwawt/macosx/CPlatformView.java \ sun/lwawt/macosx/CPlatformView.java \
sun/lwawt/macosx/CPlatformWindow.java \ sun/lwawt/macosx/CPlatformWindow.java \
sun/lwawt/macosx/CWarningWindow.java \ sun/lwawt/macosx/CWarningWindow.java \

View File

@ -305,6 +305,7 @@ SUNWprivate_1.1 {
Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap; Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap;
Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard; Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard;
Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode; Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode;
Java_sun_awt_X11_XlibWrapper_XkbSetDetectableAutoRepeat;
Java_sun_awt_X11_XlibWrapper_XGetModifierMapping; Java_sun_awt_X11_XlibWrapper_XGetModifierMapping;
Java_sun_awt_X11_XlibWrapper_XFreeModifiermap; Java_sun_awt_X11_XlibWrapper_XFreeModifiermap;
Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping; Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping;

View File

@ -65,14 +65,10 @@ $(eval $(call SetupAppletDemo,DitherTest))
$(eval $(call SetupAppletDemo,DrawTest)) $(eval $(call SetupAppletDemo,DrawTest))
$(eval $(call SetupAppletDemo,Fractal)) $(eval $(call SetupAppletDemo,Fractal))
$(eval $(call SetupAppletDemo,GraphicsTest)) $(eval $(call SetupAppletDemo,GraphicsTest))
$(eval $(call SetupAppletDemo,MoleculeViewer))
$(eval $(call SetupAppletDemo,NervousText)) $(eval $(call SetupAppletDemo,NervousText))
$(eval $(call SetupAppletDemo,SimpleGraph)) $(eval $(call SetupAppletDemo,SimpleGraph))
$(eval $(call SetupAppletDemo,SortDemo)) $(eval $(call SetupAppletDemo,SortDemo))
$(eval $(call SetupAppletDemo,SpreadSheet)) $(eval $(call SetupAppletDemo,SpreadSheet))
# Build WireFrame without a server since it
# has a class Matrix3D that also exists in MoleculeViewer.
$(eval $(call SetupAppletDemo,WireFrame,true))
ifndef OPENJDK ifndef OPENJDK
$(eval $(call SetupAppletDemo,Animator,,closed/)) $(eval $(call SetupAppletDemo,Animator,,closed/))
@ -83,7 +79,7 @@ endif
################################################################################################## ##################################################################################################
PATTERNS_TO_COPY=.html .txt .properties .js .gif .jpg .theme .data .opt README .c .h .png .ttf PATTERNS_TO_COPY=.html .txt .properties .js .gif .jpg .theme .data .opt README .c .h .png .ttf .xyz .obj
define SetupDemo define SetupDemo
# Param 1 = Name of the demo # Param 1 = Name of the demo
@ -161,6 +157,8 @@ $(JDK_OUTPUTDIR)/demo/jfc/CodePointIM/_the.services : \
BUILD_DEMOS+=$(JDK_OUTPUTDIR)/demo/jfc/CodePointIM/_the.services BUILD_DEMOS+=$(JDK_OUTPUTDIR)/demo/jfc/CodePointIM/_the.services
$(eval $(call SetupDemo,MoleculeViewer,applets,,XYZChemModel,,,example*.html XYZApp.java))
$(eval $(call SetupDemo,WireFrame,applets,,ThreeD,,,example*.html ThreeD.java))
$(eval $(call SetupDemo,FileChooserDemo,jfc,,FileChooserDemo,,,README*)) $(eval $(call SetupDemo,FileChooserDemo,jfc,,FileChooserDemo,,,README*))
$(eval $(call SetupDemo,Font2DTest,jfc,,Font2DTest,,,*.html *.txt)) $(eval $(call SetupDemo,Font2DTest,jfc,,Font2DTest,,,*.html *.txt))
$(eval $(call SetupDemo,Metalworks,jfc,,Metalworks,,,README*)) $(eval $(call SetupDemo,Metalworks,jfc,,Metalworks,,,README*))

View File

@ -62,6 +62,7 @@ ifndef OPENJDK
# AccessBridge is compiled separately below. # AccessBridge is compiled separately below.
EXFILES += AccessBridge.java \ EXFILES += AccessBridge.java \
AccessBridgeLoader.java \
com/sun/java/accessibility/util/java/awt/ChoiceTranslator.java com/sun/java/accessibility/util/java/awt/ChoiceTranslator.java
# This seems to never be built # This seems to never be built
EXCLUDES += com/sun/java/accessibility/extensions EXCLUDES += com/sun/java/accessibility/extensions

View File

@ -23,7 +23,7 @@
# questions. # questions.
# #
defalt: all default: all
include $(SPEC) include $(SPEC)
include MakeBase.gmk include MakeBase.gmk

View File

@ -23,7 +23,7 @@
# questions. # questions.
# #
defalt: all default: all
include $(SPEC) include $(SPEC)
include MakeBase.gmk include MakeBase.gmk

View File

@ -382,11 +382,16 @@ COPY_FILES += $(CACERTS_DST)
########################################################################################## ##########################################################################################
BLACKLISTED_CERTS_SRC := $(JDK_TOPDIR)/src/share/lib/security/blacklisted.certs
BLACKLISTED_CERTS_DST := $(JDK_OUTPUTDIR)/lib/security/blacklisted.certs
ifndef OPENJDK ifndef OPENJDK
BLACKLIST_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/blacklist BLACKLIST_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/blacklist
BLACKLIST_DST := $(JDK_OUTPUTDIR)/lib/security/blacklist BLACKLIST_DST := $(JDK_OUTPUTDIR)/lib/security/blacklist
BLACKLISTED_CERTS_SRC += $(wildcard $(JDK_TOPDIR)/src/closed/share/lib/security/blacklisted.certs)
TRUSTEDLIBS_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/trusted.libraries TRUSTEDLIBS_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/trusted.libraries
TRUSTEDLIBS_DST := $(JDK_OUTPUTDIR)/lib/security/trusted.libraries TRUSTEDLIBS_DST := $(JDK_OUTPUTDIR)/lib/security/trusted.libraries
@ -402,6 +407,20 @@ COPY_FILES += $(TRUSTEDLIBS_DST)
endif endif
$(BLACKLISTED_CERTS_DST): $(BLACKLISTED_CERTS_SRC)
$(MKDIR) -p $(@D)
$(CAT) $^ | $(SED) '/^$$/d' | $(SORT) | $(UNIQ) > $@.tmp
$(GREP) -i Algorithm $@.tmp > $@
if [ `$(SED) -n -e "$$=" $@` != 1 ]; then \
$(ECHO) "Different algorithms defined in $^"; \
$(RM) $@ $@.tmp; \
false; \
fi
$(GREP) -iv Algorithm $@.tmp >> $@
$(RM) $@.tmp
COPY_FILES += $(BLACKLISTED_CERTS_DST)
########################################################################################## ##########################################################################################
ifndef OPENJDK ifndef OPENJDK

View File

@ -953,13 +953,13 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
ifeq ($(OPENJDK_TARGET_CPU_BITS), 32) ifeq ($(OPENJDK_TARGET_CPU_BITS), 32)
$(eval $(call SetupArchive,BUILD_ACCESSBRIDGE_32_JAR,,\ $(eval $(call SetupArchive,BUILD_ACCESSBRIDGE_32_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes_ab/32bit $(JDK_OUTPUTDIR)/classes,\ SRCS:=$(JDK_OUTPUTDIR)/classes_ab/32bit,\
INCLUDES:=com/sun/java/accessibility,\ INCLUDES:=com/sun/java/accessibility,\
JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge-32.jar,\ JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge-32.jar,\
SKIP_METAINF:=true)) SKIP_METAINF:=true))
$(eval $(call SetupArchive,BUILD_ACCESSBRIDGE_LEGACY_JAR,,\ $(eval $(call SetupArchive,BUILD_ACCESSBRIDGE_LEGACY_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes_ab/legacy $(JDK_OUTPUTDIR)/classes,\ SRCS:=$(JDK_OUTPUTDIR)/classes_ab/legacy,\
INCLUDES:=com/sun/java/accessibility,\ INCLUDES:=com/sun/java/accessibility,\
JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge.jar,\ JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge.jar,\
SKIP_METAINF:=true)) SKIP_METAINF:=true))
@ -968,9 +968,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge.jar $(IMAGES_OUTPUTDIR)/lib/ext/access-bridge.jar
else else
$(eval $(call SetupArchive,BUILD_ACCESSBRIDGE_64_JAR,,\ $(eval $(call SetupArchive,BUILD_ACCESSBRIDGE_64_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes_ab/64bit $(JDK_OUTPUTDIR)/classes,\ SRCS:=$(JDK_OUTPUTDIR)/classes_ab/64bit,\
INCLUDES:=com/sun/java/accessibility,\ INCLUDES:=com/sun/java/accessibility,\
EXCLUDES:=com/sun/java/accessibility/util/java,\
JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge-64.jar,\ JAR:=$(IMAGES_OUTPUTDIR)/lib/ext/access-bridge-64.jar,\
SKIP_METAINF:=true)) SKIP_METAINF:=true))

View File

@ -200,26 +200,42 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
AB_SRC_DIR := $(JDK_TOPDIR)/src/closed/windows/classes/com/sun/java/accessibility AB_SRC_DIR := $(JDK_TOPDIR)/src/closed/windows/classes/com/sun/java/accessibility
ifeq ($(OPENJDK_TARGET_CPU_BITS), 32) ifeq ($(OPENJDK_TARGET_CPU_BITS), 32)
$(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridgeLoader.java: \
$(AB_SRC_DIR)/32bit/AccessBridgeLoader.java
$(install-file)
$(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridge.java: \ $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridge.java: \
$(AB_SRC_DIR)/32bit/AccessBridge.java $(AB_SRC_DIR)/AccessBridge.java
$(install-file)
$(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridgeLoader.java: \
$(AB_SRC_DIR)/legacy/AccessBridgeLoader.java
$(install-file) $(install-file)
$(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridge.java: \ $(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridge.java: \
$(AB_SRC_DIR)/legacy/AccessBridge.java $(AB_SRC_DIR)/AccessBridge.java
$(install-file) $(install-file)
GENSRC_MISC += $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridge.java \ GENSRC_MISC += $(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridgeLoader.java \
$(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridge.java $(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridgeLoader.java \
$(AB_GENSRC_DIR)/32bit/com/sun/java/accessibility/AccessBridge.java \
$(AB_GENSRC_DIR)/legacy/com/sun/java/accessibility/AccessBridge.java
else else
$(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridge.java: \ $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridgeLoader.java: \
$(AB_SRC_DIR)/64bit/AccessBridge.java $(AB_SRC_DIR)/64bit/AccessBridgeLoader.java
$(install-file) $(install-file)
GENSRC_MISC += $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridge.java $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridge.java: \
$(AB_SRC_DIR)/AccessBridge.java
$(install-file)
GENSRC_MISC += $(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridgeLoader.java \
$(AB_GENSRC_DIR)/64bit/com/sun/java/accessibility/AccessBridge.java
endif endif
endif endif
endif endif
########################################################################################## ##########################################################################################

View File

@ -253,6 +253,13 @@ ifeq ($(OPENJDK_TARGET_OS),windows)
$(call CacheFind,$(JDK_TOPDIR)/src/windows/classes/sun/awt/windows)),\ $(call CacheFind,$(JDK_TOPDIR)/src/windows/classes/sun/awt/windows)),\
ListResourceBundle,%zh_TW,%zh_HK)) ListResourceBundle,%zh_TW,%zh_HK))
endif endif
# os x specific awt properties
ifeq ($(OPENJDK_TARGET_OS),macosx)
$(eval $(call add_properties_to_compile,SUN_AWT,\
$(filter $(JDK_TOPDIR)/src/macosx/classes/sun/awt/resources/%.properties,\
$(call CacheFind,$(JDK_TOPDIR)/src/macosx/classes/sun/awt/resources)),\
ListResourceBundle))
endif
#sun/launcher/resources #sun/launcher/resources
$(eval $(call add_properties_to_compile,SUN_LAUNCHER,\ $(eval $(call add_properties_to_compile,SUN_LAUNCHER,\

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -190,6 +190,26 @@ $(foreach f,$(filter $(OVERLAY_FILTER),$(JDK_BIN_LIST)),\
$(foreach f,$(filter $(OVERLAY_FILTER),$(JDKJRE_BIN_LIST)),\ $(foreach f,$(filter $(OVERLAY_FILTER),$(JDKJRE_BIN_LIST)),\
$(eval $(call AddFileToCopy,$(JDK_OUTPUTDIR),$(JDK_OVERLAY_IMAGE_DIR)/jre,$f,JDKJRE_BIN_TARGETS))) $(eval $(call AddFileToCopy,$(JDK_OUTPUTDIR),$(JDK_OVERLAY_IMAGE_DIR)/jre,$f,JDKJRE_BIN_TARGETS)))
ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_BITS),solaris-64)
define AddIsadirLink
# Param 1 - src file
# Param 2 - variable to add targets to
$1_LINK := $$(dir $1)$(OPENJDK_TARGET_CPU_ISADIR)/$$(notdir $1)
$$($1_LINK):
$(ECHO) $(LOG_INFO) Creating link $$(patsubst $(OUTPUT_ROOT)/%,%,$$@)
$(MKDIR) -p $$(@D)
$(LN) -s ../$$(@F) $$@
$2 += $$($1_LINK)
endef
$(foreach f,$(JRE_BIN_TARGETS),$(eval $(call AddIsadirLink,$f,JRE_BIN_ISADIR_LINK_TARGETS)))
$(foreach f,$(JDK_BIN_TARGETS),$(eval $(call AddIsadirLink,$f,JDK_BIN_ISADIR_LINK_TARGETS)))
$(foreach f,$(JDKJRE_BIN_TARGETS),$(eval $(call AddIsadirLink,$f,JDKJRE_BIN_ISADIR_LINK_TARGETS)))
endif
################################################################################ ################################################################################
# /lib dir # /lib dir
ifneq ($(OPENJDK_TARGET_OS), macosx) ifneq ($(OPENJDK_TARGET_OS), macosx)
@ -730,7 +750,8 @@ endif
jre-image: $(JRE_BIN_TARGETS) $(JRE_LIB_TARGETS) $(JRE_IMAGE_DIR)/lib/applet \ jre-image: $(JRE_BIN_TARGETS) $(JRE_LIB_TARGETS) $(JRE_IMAGE_DIR)/lib/applet \
$(JRE_IMAGE_DIR)/lib/meta-index $(JRE_IMAGE_DIR)/lib/ext/meta-index \ $(JRE_IMAGE_DIR)/lib/meta-index $(JRE_IMAGE_DIR)/lib/ext/meta-index \
$(JRE_MAN_PAGE_LIST) $(JRE_DOC_TARGETS) $(JRE_INFO_FILE) $(JRE_STRIP_LIST) $(JRE_MAN_PAGE_LIST) $(JRE_DOC_TARGETS) $(JRE_INFO_FILE) $(JRE_STRIP_LIST) \
$(JRE_BIN_ISADIR_LINK_TARGETS)
jdk-image: $(JDK_BIN_TARGETS) $(JDKJRE_BIN_TARGETS) \ jdk-image: $(JDK_BIN_TARGETS) $(JDKJRE_BIN_TARGETS) \
$(JDK_LIB_TARGETS) $(JDKJRE_LIB_TARGETS) \ $(JDK_LIB_TARGETS) $(JDKJRE_LIB_TARGETS) \
@ -741,7 +762,8 @@ jdk-image: $(JDK_BIN_TARGETS) $(JDKJRE_BIN_TARGETS) \
$(JDK_DB_TARGETS) $(JDK_INCLUDE_TARGETS) \ $(JDK_DB_TARGETS) $(JDK_INCLUDE_TARGETS) \
$(JDKJRE_DOC_TARGETS) $(JDK_DOC_TARGETS) \ $(JDKJRE_DOC_TARGETS) $(JDK_DOC_TARGETS) \
$(JDK_INFO_FILE) $(JDKJRE_STRIP_LIST) $(JDK_BIN_STRIP_LIST) \ $(JDK_INFO_FILE) $(JDKJRE_STRIP_LIST) $(JDK_BIN_STRIP_LIST) \
$(JDK_IMAGE_DIR)/src.zip $(JDK_IMAGE_DIR)/src.zip \
$(JDK_BIN_ISADIR_LINK_TARGETS) $(JDKJRE_BIN_ISADIR_LINK_TARGETS)
jre-overlay-image: $(JRE_OVERLAY_BIN_TARGETS) $(JRE_OVERLAY_LIB_TARGETS) \ jre-overlay-image: $(JRE_OVERLAY_BIN_TARGETS) $(JRE_OVERLAY_LIB_TARGETS) \
$(JRE_OVERLAY_INFO_FILE) $(JRE_OVERLAY_STRIP_LIST) $(JRE_OVERLAY_INFO_FILE) $(JRE_OVERLAY_STRIP_LIST)

View File

@ -305,6 +305,7 @@ SUNWprivate_1.1 {
Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap; Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap;
Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard; Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard;
Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode; Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode;
Java_sun_awt_X11_XlibWrapper_XkbSetDetectableAutoRepeat;
Java_sun_awt_X11_XlibWrapper_XGetModifierMapping; Java_sun_awt_X11_XlibWrapper_XGetModifierMapping;
Java_sun_awt_X11_XlibWrapper_XFreeModifiermap; Java_sun_awt_X11_XlibWrapper_XFreeModifiermap;
Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping; Java_sun_awt_X11_XlibWrapper_XRefreshKeyboardMapping;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,14 +30,9 @@ import java.util.*;
import javax.script.*; import javax.script.*;
public class AppleScriptEngineFactory implements ScriptEngineFactory { public class AppleScriptEngineFactory implements ScriptEngineFactory {
private static native void initNative(); private static volatile boolean initialized = false;
static { private static native void initNative();
java.awt.Toolkit.getDefaultToolkit();
System.loadLibrary("AppleScriptEngine");
initNative();
TRACE("<static-init>");
}
static void TRACE(final String str) { static void TRACE(final String str) {
// System.out.println(AppleScriptEngineFactory.class.getName() + "." + str); // System.out.println(AppleScriptEngineFactory.class.getName() + "." + str);
@ -80,6 +75,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* *
* @return full name of the ScriptEngine * @return full name of the ScriptEngine
*/ */
@Override
public String getEngineName() { public String getEngineName() {
TRACE("getEngineName()"); TRACE("getEngineName()");
return ENGINE_NAME; return ENGINE_NAME;
@ -90,6 +86,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* *
* @return version of the ScriptEngine * @return version of the ScriptEngine
*/ */
@Override
public String getEngineVersion() { public String getEngineVersion() {
TRACE("getEngineVersion()"); TRACE("getEngineVersion()");
return ENGINE_VERSION; return ENGINE_VERSION;
@ -100,6 +97,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* *
* @return name of the language supported by the ScriptEngine(Factory) * @return name of the language supported by the ScriptEngine(Factory)
*/ */
@Override
public String getLanguageName() { public String getLanguageName() {
TRACE("getLanguageName()"); TRACE("getLanguageName()");
return LANGUAGE; return LANGUAGE;
@ -110,11 +108,12 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* *
* @return language version supported by the ScriptEngine(Factory) * @return language version supported by the ScriptEngine(Factory)
*/ */
@Override
public String getLanguageVersion() { public String getLanguageVersion() {
TRACE("getLanguageVersion()"); TRACE("getLanguageVersion()");
return AccessController.doPrivileged(new PrivilegedAction<String>() { return AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() { public String run() {
final AppleScriptEngine engine = new AppleScriptEngine(AppleScriptEngineFactory.this); final AppleScriptEngine engine = getScriptEngine();
return engine.getLanguageVersion(); return engine.getLanguageVersion();
} }
}); });
@ -126,6 +125,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* *
* @return ArrayList of file extensions AppleScript associates with * @return ArrayList of file extensions AppleScript associates with
*/ */
@Override
public List<String> getExtensions() { public List<String> getExtensions() {
TRACE("getExtensions()"); TRACE("getExtensions()");
return Arrays.asList("scpt", "applescript", "app"); return Arrays.asList("scpt", "applescript", "app");
@ -137,6 +137,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* *
* @return ArrayList of mimetypes that AppleScript associates with * @return ArrayList of mimetypes that AppleScript associates with
*/ */
@Override
public List<String> getMimeTypes() { public List<String> getMimeTypes() {
TRACE("getMimeTypes()"); TRACE("getMimeTypes()");
return Arrays.asList("application/x-applescript", "text/plain", "text/applescript"); return Arrays.asList("application/x-applescript", "text/plain", "text/applescript");
@ -148,6 +149,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* *
* @return * @return
*/ */
@Override
public List<String> getNames() { public List<String> getNames() {
TRACE("getNames()"); TRACE("getNames()");
return Arrays.asList("AppleScriptEngine", "AppleScript", "OSA"); return Arrays.asList("AppleScriptEngine", "AppleScript", "OSA");
@ -165,6 +167,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* arguments to the function * arguments to the function
* @return the AppleScript string calling the method * @return the AppleScript string calling the method
*/ */
@Override
public String getMethodCallSyntax(final String obj, final String fname, final String ... args) { public String getMethodCallSyntax(final String obj, final String fname, final String ... args) {
// StringBuilder builder = new StringBuilder(); // StringBuilder builder = new StringBuilder();
// builder.append("my " + fname + "("); // builder.append("my " + fname + "(");
@ -181,6 +184,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* @param toDisplay * @param toDisplay
* @return * @return
*/ */
@Override
public String getOutputStatement(final String toDisplay) { public String getOutputStatement(final String toDisplay) {
// TODO -- this might even be good enough? XD // TODO -- this might even be good enough? XD
return getMethodCallSyntax(null, "print", toDisplay); return getMethodCallSyntax(null, "print", toDisplay);
@ -193,8 +197,9 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* the key to look up * the key to look up
* @return the static preseeded value for the key in the ScriptEngine, if it exists, otherwise <code>null</code> * @return the static preseeded value for the key in the ScriptEngine, if it exists, otherwise <code>null</code>
*/ */
@Override
public Object getParameter(final String key) { public Object getParameter(final String key) {
final AppleScriptEngine engine = new AppleScriptEngine(this); final AppleScriptEngine engine = getScriptEngine();
if (!engine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(key)) return null; if (!engine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(key)) return null;
return engine.getBindings(ScriptContext.ENGINE_SCOPE).get(key); return engine.getBindings(ScriptContext.ENGINE_SCOPE).get(key);
} }
@ -205,6 +210,7 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* @param statements * @param statements
* @return * @return
*/ */
@Override
public String getProgram(final String ... statements) { public String getProgram(final String ... statements) {
final StringBuilder program = new StringBuilder(); final StringBuilder program = new StringBuilder();
for (final String statement : statements) { for (final String statement : statements) {
@ -218,8 +224,21 @@ public class AppleScriptEngineFactory implements ScriptEngineFactory {
* *
* @return new AppleScriptEngine with this factory as it's parent * @return new AppleScriptEngine with this factory as it's parent
*/ */
public ScriptEngine getScriptEngine() { @Override
public AppleScriptEngine getScriptEngine() {
AppleScriptEngine.checkSecurity(); AppleScriptEngine.checkSecurity();
ensureInitialized();
return new AppleScriptEngine(this); return new AppleScriptEngine(this);
} }
private static synchronized void ensureInitialized() {
if (!initialized) {
initialized = true;
java.awt.Toolkit.getDefaultToolkit();
System.loadLibrary("AppleScriptEngine");
initNative();
}
}
} }

View File

@ -42,6 +42,7 @@ import javax.swing.filechooser.*;
import javax.swing.plaf.*; import javax.swing.plaf.*;
import javax.swing.table.*; import javax.swing.table.*;
import sun.swing.AbstractFilterComboBoxModel;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
public class AquaFileChooserUI extends FileChooserUI { public class AquaFileChooserUI extends FileChooserUI {
@ -1266,64 +1267,9 @@ public class AquaFileChooserUI extends FileChooserUI {
/** /**
* Data model for a type-face selection combo-box. * Data model for a type-face selection combo-box.
*/ */
protected class FilterComboBoxModel extends DefaultListModel implements ComboBoxModel, PropertyChangeListener { protected class FilterComboBoxModel extends AbstractFilterComboBoxModel {
int selectedIndex = -1; protected JFileChooser getFileChooser() {
return AquaFileChooserUI.this.getFileChooser();
protected FilterComboBoxModel() {
super();
final FileFilter filters[] = getFileChooser().getChoosableFileFilters();
for (int i = 0; i < filters.length; i++) {
this.add(i, filters[i]);
}
}
public void propertyChange(final PropertyChangeEvent e) {
final String prop = e.getPropertyName();
if (prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
this.clear();
final FileFilter filters[] = (FileFilter[])e.getNewValue();
for (int i = 0; i < filters.length; i++) {
this.add(i, filters[i]);
}
fireContentsChanged(this, -1, -1);
} else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
final FileFilter currentFilter = (FileFilter)e.getNewValue();
FileFilter filters[] = getFileChooser().getChoosableFileFilters();
boolean found = false;
if (currentFilter != null) {
for (final FileFilter element : filters) {
if (element == currentFilter) {
found = true;
}
}
if (found == false) {
getFileChooser().addChoosableFileFilter(currentFilter);
}
}
filters = getFileChooser().getChoosableFileFilters();
setSelectedItem(e.getNewValue());
}
}
public void setSelectedItem(final Object filter) {
if (filter != null) {
selectedIndex = this.indexOf(filter);
fireContentsChanged(this, -1, -1);
}
}
public Object getSelectedItem() {
final Object returnValue = null;
if (this.size() > 0) {
if ((selectedIndex != -1) && (selectedIndex < size())) { return this.get(selectedIndex); }
}
return returnValue;
} }
} }

View File

@ -46,7 +46,7 @@ FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5
FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30 FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30
FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5 FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5
FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30
FileChooser.updateButton.textAndMnemonic=\uAC31\uC2E0 FileChooser.updateButton.textAndMnemonic=\uC5C5\uB370\uC774\uD2B8
FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0 FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0
FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30 FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30

View File

@ -0,0 +1,71 @@
#
# OS X specific AWT properties
#
# Modifier names
AWT.shift=\u21e7
AWT.control=\u2303
AWT.alt=\u2325
AWT.meta=\u2318
AWT.altGraph=\u2325
# Key names
AWT.enter=\u23ce
AWT.backSpace=\u232b
AWT.tab=\u21e5
AWT.cancel=\u238b
AWT.clear=\u2327
AWT.capsLock=\u21ea
AWT.escape=\u238b
AWT.space=\u2423
AWT.pgup=\u21de
AWT.pgdn=\u21df
AWT.end=\u2198
AWT.home=\u2196
AWT.left=\u2190
AWT.up=\u2191
AWT.right=\u2192
AWT.down=\u2193
AWT.comma=,
AWT.period=.
AWT.slash=/
AWT.semicolon=;
AWT.equals=\u003d
AWT.openBracket=[
AWT.backSlash=\\
AWT.closeBracket=]
AWT.multiply=\u2328 *
AWT.add=\u2328 +
AWT.separator=\u2328 ,
AWT.separater=\u2328 ,
AWT.subtract=\u2328 -
AWT.decimal=\u2328 .
AWT.divide=\u2328 /
AWT.delete=\u2326
AWT.printScreen=\u2399
AWT.backQuote=`
AWT.quote='
AWT.ampersand=&
AWT.asterisk=*
AWT.quoteDbl="
AWT.Less=<
AWT.greater=>
AWT.braceLeft=[
AWT.braceRight=]
AWT.at=@
AWT.colon=:
AWT.circumflex=^
AWT.dollar=$
AWT.euro=\u20ac
AWT.exclamationMark=!
AWT.invertedExclamationMark=\u00a1
AWT.leftParenthesis=(
AWT.numberSign=#
AWT.plus=+
AWT.minus=-
AWT.rightParenthesis=)
AWT.underscore=_
# Numeric Keypad
AWT.numpad=\u2328

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,10 @@ import java.awt.peer.ButtonPeer;
import javax.swing.JButton; import javax.swing.JButton;
/**
* Lightweight implementation of {@link ButtonPeer}. Delegates most of the work
* to the {@link JButton}.
*/
final class LWButtonPeer extends LWComponentPeer<Button, JButton> final class LWButtonPeer extends LWComponentPeer<Button, JButton>
implements ButtonPeer, ActionListener { implements ButtonPeer, ActionListener {
@ -42,7 +46,7 @@ final class LWButtonPeer extends LWComponentPeer<Button, JButton>
} }
@Override @Override
protected JButton createDelegate() { JButton createDelegate() {
return new JButtonDelegate(); return new JButtonDelegate();
} }
@ -74,6 +78,7 @@ final class LWButtonPeer extends LWComponentPeer<Button, JButton>
return true; return true;
} }
@SuppressWarnings("serial")// Safe: outer class is non-serializable.
private final class JButtonDelegate extends JButton { private final class JButtonDelegate extends JButton {
// Empty non private constructor was added because access to this // Empty non private constructor was added because access to this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,10 @@ import java.awt.peer.CanvasPeer;
import javax.swing.JComponent; import javax.swing.JComponent;
/**
* Lightweight implementation of {@link CanvasPeer}. This peer is empty, because
* all the components in lwawt use graphic object from the top level window.
*/
class LWCanvasPeer<T extends Component, D extends JComponent> class LWCanvasPeer<T extends Component, D extends JComponent>
extends LWComponentPeer<T, D> implements CanvasPeer { extends LWComponentPeer<T, D> implements CanvasPeer {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -41,6 +41,11 @@ import javax.swing.JRadioButton;
import javax.swing.JToggleButton; import javax.swing.JToggleButton;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
/**
* Lightweight implementation of {@link CheckboxPeer}. Delegates most of the
* work to the {@link JCheckBox} and {@link JRadioButton}, which are placed
* inside an empty {@link JComponent}.
*/
final class LWCheckboxPeer final class LWCheckboxPeer
extends LWComponentPeer<Checkbox, LWCheckboxPeer.CheckboxDelegate> extends LWComponentPeer<Checkbox, LWCheckboxPeer.CheckboxDelegate>
implements CheckboxPeer, ItemListener { implements CheckboxPeer, ItemListener {
@ -51,12 +56,12 @@ final class LWCheckboxPeer
} }
@Override @Override
protected CheckboxDelegate createDelegate() { CheckboxDelegate createDelegate() {
return new CheckboxDelegate(); return new CheckboxDelegate();
} }
@Override @Override
protected Component getDelegateFocusOwner() { Component getDelegateFocusOwner() {
return getDelegate().getCurrentButton(); return getDelegate().getCurrentButton();
} }
@ -137,6 +142,7 @@ final class LWCheckboxPeer
return true; return true;
} }
@SuppressWarnings("serial")// Safe: outer class is non-serializable.
final class CheckboxDelegate extends JComponent { final class CheckboxDelegate extends JComponent {
private final JCheckBox cb; private final JCheckBox cb;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,14 +26,18 @@
package sun.lwawt; package sun.lwawt;
import java.awt.Choice; import java.awt.*;
import java.awt.Point;
import java.awt.event.ItemEvent; import java.awt.event.ItemEvent;
import java.awt.event.ItemListener; import java.awt.event.ItemListener;
import java.awt.peer.ChoicePeer; import java.awt.peer.ChoicePeer;
import javax.swing.JComboBox; import javax.accessibility.Accessible;
import javax.swing.*;
/**
* Lightweight implementation of {@link ChoicePeer}. Delegates most of the work
* to the {@link JComboBox}.
*/
final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>> final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>>
implements ChoicePeer, ItemListener { implements ChoicePeer, ItemListener {
@ -50,7 +54,7 @@ final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>>
} }
@Override @Override
protected JComboBox<String> createDelegate() { JComboBox<String> createDelegate() {
return new JComboBoxDelegate(); return new JComboBoxDelegate();
} }
@ -128,6 +132,7 @@ final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>>
return true; return true;
} }
@SuppressWarnings("serial")// Safe: outer class is non-serializable.
private final class JComboBoxDelegate extends JComboBox<String> { private final class JComboBoxDelegate extends JComboBox<String> {
// Empty non private constructor was added because access to this // Empty non private constructor was added because access to this
@ -159,5 +164,32 @@ final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>>
} }
super.setSelectedItem(anObject); super.setSelectedItem(anObject);
} }
@Override
public void firePopupMenuWillBecomeVisible() {
super.firePopupMenuWillBecomeVisible();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JPopupMenu popupMenu = getPopupMenu();
if (popupMenu != null) {
if (popupMenu.getInvoker() != LWChoicePeer.this.getTarget()) {
popupMenu.setVisible(false);
popupMenu.show(LWChoicePeer.this.getTarget(), 0, 0);
}
}
}
});
}
private JPopupMenu getPopupMenu() {
for (int i = 0; i < getAccessibleContext().getAccessibleChildrenCount(); i++) {
Accessible child = getAccessibleContext().getAccessibleChild(i);
if (child instanceof JPopupMenu) {
return (JPopupMenu) child;
}
}
return null;
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -72,19 +72,23 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
{ {
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWComponentPeer"); private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWComponentPeer");
// State lock is to be used for modifications to this /**
// peer's fields (e.g. bounds, background, font, etc.) * State lock is to be used for modifications to this peer's fields (e.g.
// It should be the last lock in the lock chain * bounds, background, font, etc.) It should be the last lock in the lock
private final Object stateLock = * chain
new StringBuilder("LWComponentPeer.stateLock"); */
private final Object stateLock = new Object();
// The lock to operate with the peers hierarchy. AWT tree /**
// lock is not used as there are many peers related ops * The lock to operate with the peers hierarchy. AWT tree lock is not used
// to be done on the toolkit thread, and we don't want to * as there are many peers related ops to be done on the toolkit thread, and
// depend on a public lock on this thread * we don't want to depend on a public lock on this thread
private static final Object peerTreeLock = */
new StringBuilder("LWComponentPeer.peerTreeLock"); private static final Object peerTreeLock = new Object();
/**
* The associated AWT object.
*/
private final T target; private final T target;
/** /**
@ -95,7 +99,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
* the hierarchy. The exception is LWWindowPeers: their containers are * the hierarchy. The exception is LWWindowPeers: their containers are
* always null * always null
*/ */
private final LWContainerPeer containerPeer; private final LWContainerPeer<?, ?> containerPeer;
/** /**
* Handy reference to the top-level window peer. Window peer is borrowed * Handy reference to the top-level window peer. Window peer is borrowed
@ -147,11 +151,18 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
*/ */
private Image backBuffer; private Image backBuffer;
/**
* All Swing delegates use delegateContainer as a parent. This container
* intentionally do not use parent of the peer.
*/
@SuppressWarnings("serial")// Safe: outer class is non-serializable.
private final class DelegateContainer extends Container { private final class DelegateContainer extends Container {
{ {
enableEvents(0xFFFFFFFF); enableEvents(0xFFFFFFFF);
} }
// Empty non private constructor was added because access to this
// class shouldn't be emulated by a synthetic accessor method.
DelegateContainer() { DelegateContainer() {
super(); super();
} }
@ -182,7 +193,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
} }
public LWComponentPeer(T target, PlatformComponent platformComponent) { LWComponentPeer(final T target, final PlatformComponent platformComponent) {
targetPaintArea = new LWRepaintArea(); targetPaintArea = new LWRepaintArea();
this.target = target; this.target = target;
this.platformComponent = platformComponent; this.platformComponent = platformComponent;
@ -276,15 +287,18 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
* This method is called under getDelegateLock(). * This method is called under getDelegateLock().
* Overridden in subclasses. * Overridden in subclasses.
*/ */
protected D createDelegate() { D createDelegate() {
return null; return null;
} }
protected final D getDelegate() { final D getDelegate() {
return delegate; return delegate;
} }
protected Component getDelegateFocusOwner() { /**
* This method should be called under getDelegateLock().
*/
Component getDelegateFocusOwner() {
return getDelegate(); return getDelegate();
} }
@ -356,7 +370,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
// Just a helper method // Just a helper method
protected final LWContainerPeer getContainerPeer() { protected final LWContainerPeer<?, ?> getContainerPeer() {
return containerPeer; return containerPeer;
} }
@ -390,7 +404,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
protected void disposeImpl() { protected void disposeImpl() {
destroyBuffers(); destroyBuffers();
LWContainerPeer cp = getContainerPeer(); LWContainerPeer<?, ?> cp = getContainerPeer();
if (cp != null) { if (cp != null) {
cp.removeChildPeer(this); cp.removeChildPeer(this);
} }
@ -462,12 +476,13 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
sg2d.constrain(size.x, size.y, size.width, size.height, getVisibleRegion()); sg2d.constrain(size.x, size.y, size.width, size.height, getVisibleRegion());
} }
public Region getVisibleRegion() { Region getVisibleRegion() {
return computeVisibleRect(this, getRegion()); return computeVisibleRect(this, getRegion());
} }
static final Region computeVisibleRect(LWComponentPeer c, Region region) { static final Region computeVisibleRect(final LWComponentPeer<?, ?> c,
final LWContainerPeer p = c.getContainerPeer(); Region region) {
final LWContainerPeer<?, ?> p = c.getContainerPeer();
if (p != null) { if (p != null) {
final Rectangle r = c.getBounds(); final Rectangle r = c.getBounds();
region = region.getTranslatedRegion(r.x, r.y); region = region.getTranslatedRegion(r.x, r.y);
@ -612,7 +627,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
* @param p Point relative to the peer. * @param p Point relative to the peer.
* @return Cursor of the peer or null if default cursor should be used. * @return Cursor of the peer or null if default cursor should be used.
*/ */
protected Cursor getCursor(final Point p) { Cursor getCursor(final Point p) {
return getTarget().getCursor(); return getTarget().getCursor();
} }
@ -717,7 +732,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
@Override @Override
public void setEnabled(final boolean e) { public void setEnabled(final boolean e) {
boolean status = e; boolean status = e;
final LWComponentPeer cp = getContainerPeer(); final LWComponentPeer<?, ?> cp = getContainerPeer();
if (cp != null) { if (cp != null) {
status &= cp.isEnabled(); status &= cp.isEnabled();
} }
@ -802,12 +817,12 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
@Override @Override
public void setZOrder(ComponentPeer above) { public void setZOrder(final ComponentPeer above) {
LWContainerPeer cp = getContainerPeer(); LWContainerPeer<?, ?> cp = getContainerPeer();
// Don't check containerPeer for null as it can only happen // Don't check containerPeer for null as it can only happen
// for windows, but this method is overridden in // for windows, but this method is overridden in
// LWWindowPeer and doesn't call super() // LWWindowPeer and doesn't call super()
cp.setChildPeerZOrder(this, (LWComponentPeer) above); cp.setChildPeerZOrder(this, (LWComponentPeer<?, ?>) above);
} }
@Override @Override
@ -923,7 +938,9 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget()); LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
return false; return false;
} }
LWWindowPeer parentPeer = (LWWindowPeer) parentWindow.getPeer(); final LWWindowPeer parentPeer =
(LWWindowPeer) AWTAccessor.getComponentAccessor()
.getPeer(parentWindow);
if (parentPeer == null) { if (parentPeer == null) {
focusLog.fine("request rejected, parentPeer is null"); focusLog.fine("request rejected, parentPeer is null");
LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget()); LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
@ -1138,7 +1155,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
protected final void repaintParent(final Rectangle oldB) { protected final void repaintParent(final Rectangle oldB) {
final LWContainerPeer cp = getContainerPeer(); final LWContainerPeer<?, ?> cp = getContainerPeer();
if (cp != null) { if (cp != null) {
// Repaint unobscured part of the parent // Repaint unobscured part of the parent
cp.repaintPeer(cp.getContentSize().intersection(oldB)); cp.repaintPeer(cp.getContentSize().intersection(oldB));
@ -1254,6 +1271,8 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
KeyEvent ke = (KeyEvent) e; KeyEvent ke = (KeyEvent) e;
delegateEvent = new KeyEvent(getDelegateFocusOwner(), ke.getID(), ke.getWhen(), delegateEvent = new KeyEvent(getDelegateFocusOwner(), ke.getID(), ke.getWhen(),
ke.getModifiers(), ke.getKeyCode(), ke.getKeyChar(), ke.getKeyLocation()); ke.getModifiers(), ke.getKeyCode(), ke.getKeyChar(), ke.getKeyLocation());
AWTAccessor.getKeyEventAccessor().setExtendedKeyCode((KeyEvent) delegateEvent,
ke.getExtendedKeyCode());
} else if (e instanceof FocusEvent) { } else if (e instanceof FocusEvent) {
FocusEvent fe = (FocusEvent) e; FocusEvent fe = (FocusEvent) e;
delegateEvent = new FocusEvent(getDelegateFocusOwner(), fe.getID(), fe.isTemporary()); delegateEvent = new FocusEvent(getDelegateFocusOwner(), fe.getID(), fe.isTemporary());
@ -1273,7 +1292,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
/** /**
* Handler for FocusEvents. * Handler for FocusEvents.
*/ */
protected void handleJavaFocusEvent(FocusEvent e) { void handleJavaFocusEvent(final FocusEvent e) {
// Note that the peer receives all the FocusEvents from // Note that the peer receives all the FocusEvents from
// its lightweight children as well // its lightweight children as well
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance(); KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
@ -1309,7 +1328,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
* Finds a top-most visible component for the given point. The location is * Finds a top-most visible component for the given point. The location is
* specified relative to the peer's parent. * specified relative to the peer's parent.
*/ */
public LWComponentPeer findPeerAt(final int x, final int y) { LWComponentPeer<?, ?> findPeerAt(final int x, final int y) {
final Rectangle r = getBounds(); final Rectangle r = getBounds();
final Region sh = getRegion(); final Region sh = getRegion();
final boolean found = isVisible() && sh.contains(x - r.x, y - r.y); final boolean found = isVisible() && sh.contains(x - r.x, y - r.y);
@ -1326,7 +1345,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
public Point windowToLocal(Point p, LWWindowPeer wp) { public Point windowToLocal(Point p, LWWindowPeer wp) {
LWComponentPeer cp = this; LWComponentPeer<?, ?> cp = this;
while (cp != wp) { while (cp != wp) {
Rectangle cpb = cp.getBounds(); Rectangle cpb = cp.getBounds();
p.x -= cpb.x; p.x -= cpb.x;
@ -1347,7 +1366,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
public Point localToWindow(Point p) { public Point localToWindow(Point p) {
LWComponentPeer cp = getContainerPeer(); LWComponentPeer<?, ?> cp = getContainerPeer();
Rectangle r = getBounds(); Rectangle r = getBounds();
while (cp != null) { while (cp != null) {
p.x += r.x; p.x += r.x;
@ -1368,7 +1387,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
repaintPeer(getSize()); repaintPeer(getSize());
} }
public void repaintPeer(final Rectangle r) { void repaintPeer(final Rectangle r) {
final Rectangle toPaint = getSize().intersection(r); final Rectangle toPaint = getSize().intersection(r);
if (!isShowing() || toPaint.isEmpty()) { if (!isShowing() || toPaint.isEmpty()) {
return; return;
@ -1387,7 +1406,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
protected final boolean isShowing() { protected final boolean isShowing() {
synchronized (getPeerTreeLock()) { synchronized (getPeerTreeLock()) {
if (isVisible()) { if (isVisible()) {
final LWContainerPeer container = getContainerPeer(); final LWContainerPeer<?, ?> container = getContainerPeer();
return (container == null) || container.isShowing(); return (container == null) || container.isShowing();
} }
} }
@ -1395,8 +1414,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
/** /**
* Paints the peer. Overridden in subclasses to delegate the actual painting * Paints the peer. Delegate the actual painting to Swing components.
* to Swing components.
*/ */
protected final void paintPeer(final Graphics g) { protected final void paintPeer(final Graphics g) {
final D delegate = getDelegate(); final D delegate = getDelegate();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -41,32 +41,25 @@ import java.util.List;
import javax.swing.JComponent; import javax.swing.JComponent;
abstract class LWContainerPeer<T extends Container, D extends JComponent> abstract class LWContainerPeer<T extends Container, D extends JComponent>
extends LWCanvasPeer<T, D> extends LWCanvasPeer<T, D> implements ContainerPeer {
implements ContainerPeer
{
// List of child peers sorted by z-order from bottom-most
// to top-most
private List<LWComponentPeer> childPeers =
new LinkedList<LWComponentPeer>();
LWContainerPeer(T target, PlatformComponent platformComponent) { /**
* List of child peers sorted by z-order from bottom-most to top-most.
*/
private final List<LWComponentPeer<?, ?>> childPeers = new LinkedList<>();
LWContainerPeer(final T target, final PlatformComponent platformComponent) {
super(target, platformComponent); super(target, platformComponent);
} }
void addChildPeer(LWComponentPeer child) { final void addChildPeer(final LWComponentPeer<?, ?> child) {
synchronized (getPeerTreeLock()) { synchronized (getPeerTreeLock()) {
addChildPeer(child, childPeers.size()); childPeers.add(childPeers.size(), child);
// TODO: repaint
} }
} }
void addChildPeer(LWComponentPeer child, int index) { final void removeChildPeer(final LWComponentPeer<?, ?> child) {
synchronized (getPeerTreeLock()) {
childPeers.add(index, child);
}
// TODO: repaint
}
void removeChildPeer(LWComponentPeer child) {
synchronized (getPeerTreeLock()) { synchronized (getPeerTreeLock()) {
childPeers.remove(child); childPeers.remove(child);
} }
@ -74,7 +67,8 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
} }
// Used by LWComponentPeer.setZOrder() // Used by LWComponentPeer.setZOrder()
void setChildPeerZOrder(LWComponentPeer peer, LWComponentPeer above) { final void setChildPeerZOrder(final LWComponentPeer<?, ?> peer,
final LWComponentPeer<?, ?> above) {
synchronized (getPeerTreeLock()) { synchronized (getPeerTreeLock()) {
childPeers.remove(peer); childPeers.remove(peer);
int index = (above != null) ? childPeers.indexOf(above) : childPeers.size(); int index = (above != null) ? childPeers.indexOf(above) : childPeers.size();
@ -98,25 +92,27 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
} }
@Override @Override
public void beginValidate() { public final void beginValidate() {
// TODO: it seems that begin/endValidate() is only useful
// for heavyweight windows, when a batch movement for
// child windows occurs. That's why no-op
}
@Override
public void endValidate() {
// TODO: it seems that begin/endValidate() is only useful // TODO: it seems that begin/endValidate() is only useful
// for heavyweight windows, when a batch movement for // for heavyweight windows, when a batch movement for
// child windows occurs. That's why no-op // child windows occurs. That's why no-op
} }
@Override @Override
public void beginLayout() { public final void endValidate() {
// TODO: it seems that begin/endValidate() is only useful
// for heavyweight windows, when a batch movement for
// child windows occurs. That's why no-op
}
@Override
public final void beginLayout() {
// Skip all painting till endLayout() // Skip all painting till endLayout()
setLayouting(true); setLayouting(true);
} }
@Override @Override
public void endLayout() { public final void endLayout() {
setLayouting(false); setLayouting(false);
// Post an empty event to flush all the pending target paints // Post an empty event to flush all the pending target paints
@ -125,18 +121,19 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
// ---- PEER NOTIFICATIONS ---- // // ---- PEER NOTIFICATIONS ---- //
/* /**
* Returns a copy of the childPeer collection. * Returns a copy of the childPeer collection.
*/ */
protected List<LWComponentPeer> getChildren() { @SuppressWarnings("unchecked")
final List<LWComponentPeer<?, ?>> getChildren() {
synchronized (getPeerTreeLock()) { synchronized (getPeerTreeLock()) {
Object copy = ((LinkedList)childPeers).clone(); Object copy = ((LinkedList<?>) childPeers).clone();
return (List<LWComponentPeer>)copy; return (List<LWComponentPeer<?, ?>>) copy;
} }
} }
@Override @Override
public final Region getVisibleRegion() { final Region getVisibleRegion() {
return cutChildren(super.getVisibleRegion(), null); return cutChildren(super.getVisibleRegion(), null);
} }
@ -144,9 +141,9 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
* Removes bounds of children above specific child from the region. If above * Removes bounds of children above specific child from the region. If above
* is null removes all bounds of children. * is null removes all bounds of children.
*/ */
protected final Region cutChildren(Region r, final LWComponentPeer above) { final Region cutChildren(Region r, final LWComponentPeer<?, ?> above) {
boolean aboveFound = above == null; boolean aboveFound = above == null;
for (final LWComponentPeer child : getChildren()) { for (final LWComponentPeer<?, ?> child : getChildren()) {
if (!aboveFound && child == above) { if (!aboveFound && child == above) {
aboveFound = true; aboveFound = true;
continue; continue;
@ -170,8 +167,8 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
* specified relative to the peer's parent. * specified relative to the peer's parent.
*/ */
@Override @Override
public final LWComponentPeer findPeerAt(int x, int y) { final LWComponentPeer<?, ?> findPeerAt(int x, int y) {
LWComponentPeer peer = super.findPeerAt(x, y); LWComponentPeer<?, ?> peer = super.findPeerAt(x, y);
final Rectangle r = getBounds(); final Rectangle r = getBounds();
// Translate to this container's coordinates to pass to children // Translate to this container's coordinates to pass to children
x -= r.x; x -= r.x;
@ -179,7 +176,7 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
if (peer != null && getContentSize().contains(x, y)) { if (peer != null && getContentSize().contains(x, y)) {
synchronized (getPeerTreeLock()) { synchronized (getPeerTreeLock()) {
for (int i = childPeers.size() - 1; i >= 0; --i) { for (int i = childPeers.size() - 1; i >= 0; --i) {
LWComponentPeer p = childPeers.get(i).findPeerAt(x, y); LWComponentPeer<?, ?> p = childPeers.get(i).findPeerAt(x, y);
if (p != null) { if (p != null) {
peer = p; peer = p;
break; break;
@ -195,7 +192,7 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
* peers should be repainted * peers should be repainted
*/ */
@Override @Override
public final void repaintPeer(final Rectangle r) { final void repaintPeer(final Rectangle r) {
final Rectangle toPaint = getSize().intersection(r); final Rectangle toPaint = getSize().intersection(r);
if (!isShowing() || toPaint.isEmpty()) { if (!isShowing() || toPaint.isEmpty()) {
return; return;
@ -208,13 +205,13 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
repaintChildren(toPaint); repaintChildren(toPaint);
} }
/* /**
* Paints all the child peers in the straight z-order, so the * Paints all the child peers in the straight z-order, so the
* bottom-most ones are painted first. * bottom-most ones are painted first.
*/ */
private void repaintChildren(final Rectangle r) { private void repaintChildren(final Rectangle r) {
final Rectangle content = getContentSize(); final Rectangle content = getContentSize();
for (final LWComponentPeer child : getChildren()) { for (final LWComponentPeer<?, ?> child : getChildren()) {
final Rectangle childBounds = child.getBounds(); final Rectangle childBounds = child.getBounds();
Rectangle toPaint = r.intersection(childBounds); Rectangle toPaint = r.intersection(childBounds);
toPaint = toPaint.intersection(content); toPaint = toPaint.intersection(content);
@ -223,21 +220,21 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
} }
} }
protected Rectangle getContentSize() { Rectangle getContentSize() {
return getSize(); return getSize();
} }
@Override @Override
public void setEnabled(final boolean e) { public void setEnabled(final boolean e) {
super.setEnabled(e); super.setEnabled(e);
for (final LWComponentPeer child : getChildren()) { for (final LWComponentPeer<?, ?> child : getChildren()) {
child.setEnabled(e && child.getTarget().isEnabled()); child.setEnabled(e && child.getTarget().isEnabled());
} }
} }
@Override @Override
public void setBackground(final Color c) { public void setBackground(final Color c) {
for (final LWComponentPeer child : getChildren()) { for (final LWComponentPeer<?, ?> child : getChildren()) {
if (!child.getTarget().isBackgroundSet()) { if (!child.getTarget().isBackgroundSet()) {
child.setBackground(c); child.setBackground(c);
} }
@ -247,7 +244,7 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
@Override @Override
public void setForeground(final Color c) { public void setForeground(final Color c) {
for (final LWComponentPeer child : getChildren()) { for (final LWComponentPeer<?, ?> child : getChildren()) {
if (!child.getTarget().isForegroundSet()) { if (!child.getTarget().isForegroundSet()) {
child.setForeground(c); child.setForeground(c);
} }
@ -257,7 +254,7 @@ abstract class LWContainerPeer<T extends Container, D extends JComponent>
@Override @Override
public void setFont(final Font f) { public void setFont(final Font f) {
for (final LWComponentPeer child : getChildren()) { for (final LWComponentPeer<?, ?> child : getChildren()) {
if (!child.getTarget().isFontSet()) { if (!child.getTarget().isFontSet()) {
child.setFont(f); child.setFont(f);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,7 @@ import java.awt.Point;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import sun.awt.AWTAccessor;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
public abstract class LWCursorManager { public abstract class LWCursorManager {
@ -105,11 +106,13 @@ public abstract class LWCursorManager {
c = peer.getTarget(); c = peer.getTarget();
if (c instanceof Container) { if (c instanceof Container) {
final Point p = peer.getLocationOnScreen(); final Point p = peer.getLocationOnScreen();
c = ((Container) c).findComponentAt(cursorPos.x - p.x, c = AWTAccessor.getContainerAccessor().findComponentAt(
cursorPos.y - p.y); (Container) c, cursorPos.x - p.x, cursorPos.y - p.y, false);
} }
while (c != null) { while (c != null) {
if (c.isVisible() && c.isEnabled() && (c.getPeer() != null)) { final Object p = AWTAccessor.getComponentAccessor().getPeer(c);
if (c.isVisible() && c.isEnabled() && p != null) {
break; break;
} }
c = c.getParent(); c = c.getParent();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -44,7 +44,7 @@ final class LWLabelPeer extends LWComponentPeer<Label, JLabel>
} }
@Override @Override
protected JLabel createDelegate() { JLabel createDelegate() {
return new JLabel(); return new JLabel();
} }

View File

@ -34,6 +34,8 @@ import java.awt.dnd.DropTarget;
import sun.awt.CausedFocusEvent; import sun.awt.CausedFocusEvent;
import sun.awt.LightweightFrame; import sun.awt.LightweightFrame;
import sun.swing.JLightweightFrame;
import sun.swing.SwingAccessor;
public class LWLightweightFramePeer extends LWWindowPeer { public class LWLightweightFramePeer extends LWWindowPeer {
@ -90,11 +92,6 @@ public class LWLightweightFramePeer extends LWWindowPeer {
setBounds(x, y, w, h, op, true, false); setBounds(x, y, w, h, op, true, false);
} }
@Override
public void updateCursorImmediately() {
// TODO: tries to switch to the awt/fx toolkit thread and causes a deadlock on macosx
}
@Override @Override
public void addDropTarget(DropTarget dt) { public void addDropTarget(DropTarget dt) {
} }
@ -112,4 +109,9 @@ public class LWLightweightFramePeer extends LWWindowPeer {
public void ungrab() { public void ungrab() {
getLwTarget().ungrabFocus(); getLwTarget().ungrabFocus();
} }
@Override
public void updateCursorImmediately() {
SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget());
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,7 +33,8 @@ import java.awt.peer.ListPeer;
import java.util.Arrays; import java.util.Arrays;
/** /**
* Lightweight implementation of {@link ListPeer}. * Lightweight implementation of {@link ListPeer}. Delegates most of the work to
* the {@link JList}, which is placed inside {@link JScrollPane}.
*/ */
final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList> final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>
implements ListPeer { implements ListPeer {
@ -56,7 +57,7 @@ final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>
} }
@Override @Override
protected ScrollableJList createDelegate() { ScrollableJList createDelegate() {
return new ScrollableJList(); return new ScrollableJList();
} }
@ -78,7 +79,7 @@ final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>
} }
@Override @Override
protected Component getDelegateFocusOwner() { Component getDelegateFocusOwner() {
return getDelegate().getView(); return getDelegate().getView();
} }
@ -193,6 +194,7 @@ final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>
} }
} }
@SuppressWarnings("serial")// Safe: outer class is non-serializable.
final class ScrollableJList extends JScrollPane implements ListSelectionListener { final class ScrollableJList extends JScrollPane implements ListSelectionListener {
private boolean skipStateChangedEvent; private boolean skipStateChangedEvent;
@ -234,9 +236,10 @@ final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>
} }
@Override @Override
@SuppressWarnings("unchecked")
public void valueChanged(final ListSelectionEvent e) { public void valueChanged(final ListSelectionEvent e) {
if (!e.getValueIsAdjusting() && !isSkipStateChangedEvent()) { if (!e.getValueIsAdjusting() && !isSkipStateChangedEvent()) {
final JList source = (JList) e.getSource(); final JList<?> source = (JList<?>) e.getSource();
for(int i = 0 ; i < source.getModel().getSize(); i++) { for(int i = 0 ; i < source.getModel().getSize(); i++) {
final boolean wasSelected = Arrays.binarySearch(oldSelectedIndices, i) >= 0; final boolean wasSelected = Arrays.binarySearch(oldSelectedIndices, i) >= 0;
@ -255,6 +258,7 @@ final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>
} }
} }
@SuppressWarnings("unchecked")
public JList<String> getView() { public JList<String> getView() {
return (JList<String>) getViewport().getView(); return (JList<String>) getViewport().getView();
} }
@ -289,7 +293,7 @@ final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList>
private final class JListDelegate extends JList<String> { private final class JListDelegate extends JList<String> {
JListDelegate() { JListDelegate() {
super(ScrollableJList.this.model); super(model);
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,10 +30,9 @@ import java.awt.Window;
import java.awt.peer.MouseInfoPeer; import java.awt.peer.MouseInfoPeer;
public class LWMouseInfoPeer implements MouseInfoPeer { import sun.awt.AWTAccessor;
public LWMouseInfoPeer() { public class LWMouseInfoPeer implements MouseInfoPeer {
}
@Override @Override
public int fillPointWithCoords(Point point) { public int fillPointWithCoords(Point point) {
@ -52,7 +51,7 @@ public class LWMouseInfoPeer implements MouseInfoPeer {
return false; return false;
} }
LWWindowPeer windowPeer = (LWWindowPeer)w.getPeer(); final Object windowPeer = AWTAccessor.getComponentAccessor().getPeer(w);
return LWWindowPeer.getWindowUnderCursor() == windowPeer; return LWWindowPeer.getWindowUnderCursor() == windowPeer;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,10 @@ import java.awt.peer.PanelPeer;
import javax.swing.JPanel; import javax.swing.JPanel;
/**
* Lightweight implementation of {@link PanelPeer}. Delegates most of the work
* to the {@link JPanel}.
*/
final class LWPanelPeer extends LWContainerPeer<Panel, JPanel> final class LWPanelPeer extends LWContainerPeer<Panel, JPanel>
implements PanelPeer { implements PanelPeer {
@ -39,7 +43,7 @@ final class LWPanelPeer extends LWContainerPeer<Panel, JPanel>
} }
@Override @Override
public JPanel createDelegate() { JPanel createDelegate() {
return new JPanel(); return new JPanel();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,39 +26,38 @@
package sun.lwawt; package sun.lwawt;
import sun.awt.RepaintArea;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
import sun.awt.AWTAccessor;
import sun.awt.RepaintArea;
/** /**
* Emulates appearance of heavyweight components before call of the user code.
*
* @author Sergey Bylokhov * @author Sergey Bylokhov
*/ */
final class LWRepaintArea extends RepaintArea { final class LWRepaintArea extends RepaintArea {
@Override @Override
protected void updateComponent(final Component comp, final Graphics g) { protected void updateComponent(final Component comp, final Graphics g) {
// We shouldn't paint native component as a result of UPDATE events,
// just flush onscreen back-buffer.
if (comp != null) { if (comp != null) {
super.updateComponent(comp, g); super.updateComponent(comp, g);
flushBuffers((LWComponentPeer) comp.getPeer()); LWComponentPeer.flushOnscreenGraphics();
} }
} }
@Override @Override
protected void paintComponent(final Component comp, final Graphics g) { protected void paintComponent(final Component comp, final Graphics g) {
if (comp != null) { if (comp != null) {
final LWComponentPeer peer = (LWComponentPeer) comp.getPeer(); Object peer = AWTAccessor.getComponentAccessor().getPeer(comp);
if (peer != null) { if (peer != null) {
peer.paintPeer(g); ((LWComponentPeer<?, ?>) peer).paintPeer(g);
} }
super.paintComponent(comp, g); super.paintComponent(comp, g);
flushBuffers(peer); LWComponentPeer.flushOnscreenGraphics();
}
}
private static void flushBuffers(final LWComponentPeer peer) {
if (peer != null) {
peer.flushOnscreenGraphics();
} }
} }
} }

View File

@ -34,10 +34,14 @@ import java.awt.peer.ScrollbarPeer;
import javax.swing.JScrollBar; import javax.swing.JScrollBar;
/**
* Lightweight implementation of {@link ScrollbarPeer}. Delegates most of the
* work to the {@link JScrollBar}.
*/
final class LWScrollBarPeer extends LWComponentPeer<Scrollbar, JScrollBar> final class LWScrollBarPeer extends LWComponentPeer<Scrollbar, JScrollBar>
implements ScrollbarPeer, AdjustmentListener { implements ScrollbarPeer, AdjustmentListener {
//JScrollBar fires two changes with firePropertyChange (one for old value // JScrollBar fires two changes with firePropertyChange (one for old value
// and one for new one. // and one for new one.
// We save the last value and don't fire event if not changed. // We save the last value and don't fire event if not changed.
private int currentValue; private int currentValue;
@ -48,7 +52,7 @@ final class LWScrollBarPeer extends LWComponentPeer<Scrollbar, JScrollBar>
} }
@Override @Override
protected JScrollBar createDelegate() { JScrollBar createDelegate() {
return new JScrollBar(); return new JScrollBar();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,10 @@ import java.awt.event.MouseWheelEvent;
import java.awt.peer.ScrollPanePeer; import java.awt.peer.ScrollPanePeer;
import java.util.List; import java.util.List;
/**
* Lightweight implementation of {@link ScrollPanePeer}. Delegates most of the
* work to the {@link JScrollPane}.
*/
final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane> final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane>
implements ScrollPanePeer, ChangeListener { implements ScrollPanePeer, ChangeListener {
@ -41,7 +45,8 @@ final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane>
super(target, platformComponent); super(target, platformComponent);
} }
protected JScrollPane createDelegate() { @Override
JScrollPane createDelegate() {
final JScrollPane sp = new JScrollPane(); final JScrollPane sp = new JScrollPane();
final JPanel panel = new JPanel(); final JPanel panel = new JPanel();
panel.setOpaque(false); panel.setOpaque(false);
@ -72,7 +77,7 @@ final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane>
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
final LWComponentPeer viewPeer = getViewPeer(); final LWComponentPeer<?, ?> viewPeer = getViewPeer();
if (viewPeer != null) { if (viewPeer != null) {
final Rectangle r; final Rectangle r;
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
@ -96,14 +101,13 @@ final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane>
} }
} }
LWComponentPeer getViewPeer() { LWComponentPeer<?, ?> getViewPeer() {
List<LWComponentPeer> peerList = getChildren(); final List<LWComponentPeer<?, ?>> peerList = getChildren();
return peerList.isEmpty() ? null : peerList.get(0); return peerList.isEmpty() ? null : peerList.get(0);
} }
@Override @Override
protected Rectangle getContentSize() { Rectangle getContentSize() {
Rectangle viewRect = getDelegate().getViewport().getViewRect(); Rectangle viewRect = getDelegate().getViewport().getViewRect();
return new Rectangle(viewRect.width, viewRect.height); return new Rectangle(viewRect.width, viewRect.height);
} }
@ -112,7 +116,7 @@ final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane>
public void layout() { public void layout() {
super.layout(); super.layout();
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
LWComponentPeer viewPeer = getViewPeer(); final LWComponentPeer<?, ?> viewPeer = getViewPeer();
if (viewPeer != null) { if (viewPeer != null) {
Component view = getDelegate().getViewport().getView(); Component view = getDelegate().getViewport().getView();
view.setBounds(viewPeer.getBounds()); view.setBounds(viewPeer.getBounds());

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -44,7 +44,7 @@ import javax.swing.text.JTextComponent;
/** /**
* Lightweight implementation of {@link TextAreaPeer}. Delegates most of the * Lightweight implementation of {@link TextAreaPeer}. Delegates most of the
* work to the {@link JTextArea} inside JScrollPane. * work to the {@link JTextArea} inside {@link JScrollPane}.
*/ */
final class LWTextAreaPeer final class LWTextAreaPeer
extends LWTextComponentPeer<TextArea, LWTextAreaPeer.ScrollableJTextArea> extends LWTextComponentPeer<TextArea, LWTextAreaPeer.ScrollableJTextArea>
@ -66,7 +66,7 @@ final class LWTextAreaPeer
} }
@Override @Override
protected ScrollableJTextArea createDelegate() { ScrollableJTextArea createDelegate() {
return new ScrollableJTextArea(); return new ScrollableJTextArea();
} }
@ -85,7 +85,7 @@ final class LWTextAreaPeer
} }
@Override @Override
protected Cursor getCursor(final Point p) { Cursor getCursor(final Point p) {
final boolean isContains; final boolean isContains;
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
isContains = getDelegate().getViewport().getBounds().contains(p); isContains = getDelegate().getViewport().getBounds().contains(p);
@ -94,7 +94,7 @@ final class LWTextAreaPeer
} }
@Override @Override
protected Component getDelegateFocusOwner() { Component getDelegateFocusOwner() {
return getTextComponent(); return getTextComponent();
} }
@ -200,7 +200,7 @@ final class LWTextAreaPeer
} }
} }
@SuppressWarnings("serial") @SuppressWarnings("serial")// Safe: outer class is non-serializable.
final class ScrollableJTextArea extends JScrollPane { final class ScrollableJTextArea extends JScrollPane {
ScrollableJTextArea() { ScrollableJTextArea() {
@ -218,7 +218,6 @@ final class LWTextAreaPeer
super.setEnabled(enabled); super.setEnabled(enabled);
} }
@SuppressWarnings("serial")
private final class JTextAreaDelegate extends JTextArea { private final class JTextAreaDelegate extends JTextArea {
// Empty non private constructor was added because access to this // Empty non private constructor was added because access to this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -44,11 +44,14 @@ import javax.swing.event.DocumentListener;
import javax.swing.text.Document; import javax.swing.text.Document;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
/**
* Lightweight implementation of {@link TextComponentPeer}. Provides useful
* methods for {@link LWTextAreaPeer} and {@link LWTextFieldPeer}
*/
abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent> abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent>
extends LWComponentPeer<T, D> extends LWComponentPeer<T, D>
implements DocumentListener, TextComponentPeer, InputMethodListener { implements DocumentListener, TextComponentPeer, InputMethodListener {
private volatile boolean firstChangeSkipped; private volatile boolean firstChangeSkipped;
LWTextComponentPeer(final T target, LWTextComponentPeer(final T target,
@ -218,14 +221,14 @@ abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent
} }
@Override @Override
public void inputMethodTextChanged(InputMethodEvent event) { public void inputMethodTextChanged(final InputMethodEvent event) {
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
AWTAccessor.getComponentAccessor().processEvent(getTextComponent(), event); AWTAccessor.getComponentAccessor().processEvent(getTextComponent(), event);
} }
} }
@Override @Override
public void caretPositionChanged(InputMethodEvent event) { public void caretPositionChanged(final InputMethodEvent event) {
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
AWTAccessor.getComponentAccessor().processEvent(getTextComponent(), event); AWTAccessor.getComponentAccessor().processEvent(getTextComponent(), event);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,6 +37,10 @@ import java.awt.peer.TextFieldPeer;
import javax.swing.*; import javax.swing.*;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
/**
* Lightweight implementation of {@link TextFieldPeer}. Delegates most of the
* work to the {@link JPasswordField}.
*/
final class LWTextFieldPeer final class LWTextFieldPeer
extends LWTextComponentPeer<TextField, JPasswordField> extends LWTextComponentPeer<TextField, JPasswordField>
implements TextFieldPeer, ActionListener { implements TextFieldPeer, ActionListener {
@ -47,7 +51,7 @@ final class LWTextFieldPeer
} }
@Override @Override
protected JPasswordField createDelegate() { JPasswordField createDelegate() {
return new JPasswordFieldDelegate(); return new JPasswordFieldDelegate();
} }
@ -107,7 +111,7 @@ final class LWTextFieldPeer
* @param e the focus event * @param e the focus event
*/ */
@Override @Override
protected void handleJavaFocusEvent(final FocusEvent e) { void handleJavaFocusEvent(final FocusEvent e) {
if (e.getID() == FocusEvent.FOCUS_LOST) { if (e.getID() == FocusEvent.FOCUS_LOST) {
// In order to de-select the selection // In order to de-select the selection
setCaretPosition(0); setCaretPosition(0);
@ -115,6 +119,7 @@ final class LWTextFieldPeer
super.handleJavaFocusEvent(e); super.handleJavaFocusEvent(e);
} }
@SuppressWarnings("serial")// Safe: outer class is non-serializable.
private final class JPasswordFieldDelegate extends JPasswordField { private final class JPasswordFieldDelegate extends JPasswordField {
// Empty non private constructor was added because access to this // Empty non private constructor was added because access to this

View File

@ -557,16 +557,18 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
} }
@Override @Override
public void grab(Window w) { public void grab(final Window w) {
if (w.getPeer() != null) { final Object peer = AWTAccessor.getComponentAccessor().getPeer(w);
((LWWindowPeer)w.getPeer()).grab(); if (peer != null) {
((LWWindowPeer) peer).grab();
} }
} }
@Override @Override
public void ungrab(Window w) { public void ungrab(final Window w) {
if (w.getPeer() != null) { final Object peer = AWTAccessor.getComponentAccessor().getPeer(w);
((LWWindowPeer)w.getPeer()).ungrab(false); if (peer != null) {
((LWWindowPeer) peer).ungrab(false);
} }
} }

View File

@ -43,7 +43,7 @@ public class LWWindowPeer
extends LWContainerPeer<Window, JComponent> extends LWContainerPeer<Window, JComponent>
implements FramePeer, DialogPeer, FullScreenCapable, DisplayChangedListener, PlatformEventNotifier implements FramePeer, DialogPeer, FullScreenCapable, DisplayChangedListener, PlatformEventNotifier
{ {
public static enum PeerType { public enum PeerType {
SIMPLEWINDOW, SIMPLEWINDOW,
FRAME, FRAME,
DIALOG, DIALOG,
@ -83,15 +83,15 @@ public class LWWindowPeer
// A peer where the last mouse event came to. Used by cursor manager to // A peer where the last mouse event came to. Used by cursor manager to
// find the component under cursor // find the component under cursor
private static volatile LWComponentPeer lastCommonMouseEventPeer = null; private static volatile LWComponentPeer<?, ?> lastCommonMouseEventPeer;
// A peer where the last mouse event came to. Used to generate // A peer where the last mouse event came to. Used to generate
// MOUSE_ENTERED/EXITED notifications // MOUSE_ENTERED/EXITED notifications
private volatile LWComponentPeer lastMouseEventPeer; private volatile LWComponentPeer<?, ?> lastMouseEventPeer;
// Peers where all dragged/released events should come to, // Peers where all dragged/released events should come to,
// depending on what mouse button is being dragged according to Cocoa // depending on what mouse button is being dragged according to Cocoa
private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3]; private static final LWComponentPeer<?, ?>[] mouseDownTarget = new LWComponentPeer<?, ?>[3];
// A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events // A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events
// on MOUSE_RELEASE. Click events are only generated if there were no drag // on MOUSE_RELEASE. Click events are only generated if there were no drag
@ -129,7 +129,8 @@ public class LWWindowPeer
this.peerType = peerType; this.peerType = peerType;
Window owner = target.getOwner(); Window owner = target.getOwner();
LWWindowPeer ownerPeer = (owner != null) ? (LWWindowPeer)owner.getPeer() : null; LWWindowPeer ownerPeer = owner == null ? null :
(LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(owner);
PlatformWindow ownerDelegate = (ownerPeer != null) ? ownerPeer.getPlatformWindow() : null; PlatformWindow ownerDelegate = (ownerPeer != null) ? ownerPeer.getPlatformWindow() : null;
// The delegate.initialize() needs a non-null GC on X11. // The delegate.initialize() needs a non-null GC on X11.
@ -163,10 +164,10 @@ public class LWWindowPeer
// Init warning window(for applets) // Init warning window(for applets)
SecurityWarningWindow warn = null; SecurityWarningWindow warn = null;
if (((Window)target).getWarningString() != null) { if (target.getWarningString() != null) {
// accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip // accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip
// and TrayIcon balloon windows without a warning window. // and TrayIcon balloon windows without a warning window.
if (!AWTAccessor.getWindowAccessor().isTrayIconWindow((Window)target)) { if (!AWTAccessor.getWindowAccessor().isTrayIconWindow(target)) {
LWToolkit toolkit = (LWToolkit)Toolkit.getDefaultToolkit(); LWToolkit toolkit = (LWToolkit)Toolkit.getDefaultToolkit();
warn = toolkit.createSecurityWarning(target, this); warn = toolkit.createSecurityWarning(target, this);
} }
@ -210,6 +211,7 @@ public class LWWindowPeer
} }
// Just a helper method // Just a helper method
@Override
public PlatformWindow getPlatformWindow() { public PlatformWindow getPlatformWindow() {
return platformWindow; return platformWindow;
} }
@ -391,7 +393,8 @@ public class LWWindowPeer
@Override @Override
public void setModalBlocked(Dialog blocker, boolean blocked) { public void setModalBlocked(Dialog blocker, boolean blocked) {
synchronized (getPeerTreeLock()) { synchronized (getPeerTreeLock()) {
this.blocker = blocked ? (LWWindowPeer)blocker.getPeer() : null; this.blocker = !blocked ? null :
(LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(blocker);
} }
platformWindow.setModalBlocked(blocked); platformWindow.setModalBlocked(blocked);
@ -458,6 +461,7 @@ public class LWWindowPeer
textured = isTextured; textured = isTextured;
} }
@Override
public final boolean isTranslucent() { public final boolean isTranslucent() {
synchronized (getStateLock()) { synchronized (getStateLock()) {
/* /*
@ -537,7 +541,8 @@ public class LWWindowPeer
public void blockWindows(List<Window> windows) { public void blockWindows(List<Window> windows) {
//TODO: LWX will probably need some collectJavaToplevels to speed this up //TODO: LWX will probably need some collectJavaToplevels to speed this up
for (Window w : windows) { for (Window w : windows) {
WindowPeer wp = (WindowPeer)w.getPeer(); WindowPeer wp =
(WindowPeer) AWTAccessor.getComponentAccessor().getPeer(w);
if (wp != null) { if (wp != null) {
wp.setModalBlocked((Dialog)getTarget(), true); wp.setModalBlocked((Dialog)getTarget(), true);
} }
@ -694,7 +699,7 @@ public class LWWindowPeer
// TODO: fill "bdata" member of AWTEvent // TODO: fill "bdata" member of AWTEvent
Rectangle r = getBounds(); Rectangle r = getBounds();
// findPeerAt() expects parent coordinates // findPeerAt() expects parent coordinates
LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); LWComponentPeer<?, ?> targetPeer = findPeerAt(r.x + x, r.y + y);
if (id == MouseEvent.MOUSE_EXITED) { if (id == MouseEvent.MOUSE_EXITED) {
isMouseOver = false; isMouseOver = false;
@ -743,7 +748,7 @@ public class LWWindowPeer
screenX, screenY, modifiers, clickCount, popupTrigger, screenX, screenY, modifiers, clickCount, popupTrigger,
targetPeer); targetPeer);
} else { } else {
LWComponentPeer topmostTargetPeer = LWComponentPeer<?, ?> topmostTargetPeer =
topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null; topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null;
topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y, topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y,
screenX, screenY, modifiers, clickCount, popupTrigger, screenX, screenY, modifiers, clickCount, popupTrigger,
@ -840,7 +845,7 @@ public class LWWindowPeer
private void generateMouseEnterExitEventsForComponents(long when, private void generateMouseEnterExitEventsForComponents(long when,
int button, int x, int y, int screenX, int screenY, int button, int x, int y, int screenX, int screenY,
int modifiers, int clickCount, boolean popupTrigger, int modifiers, int clickCount, boolean popupTrigger,
LWComponentPeer targetPeer) { final LWComponentPeer<?, ?> targetPeer) {
if (!isMouseOver || targetPeer == lastMouseEventPeer) { if (!isMouseOver || targetPeer == lastMouseEventPeer) {
return; return;
@ -899,7 +904,7 @@ public class LWWindowPeer
// TODO: could we just use the last mouse event target here? // TODO: could we just use the last mouse event target here?
Rectangle r = getBounds(); Rectangle r = getBounds();
// findPeerAt() expects parent coordinates // findPeerAt() expects parent coordinates
final LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); final LWComponentPeer<?, ?> targetPeer = findPeerAt(r.x + x, r.y + y);
if (targetPeer == null || !targetPeer.isEnabled()) { if (targetPeer == null || !targetPeer.isEnabled()) {
return; return;
} }
@ -933,7 +938,12 @@ public class LWWindowPeer
focusOwner = this.getTarget(); focusOwner = this.getTarget();
} }
} }
postEvent(new KeyEvent(focusOwner, id, when, modifiers, keyCode, keyChar, keyLocation));
KeyEvent keyEvent = new KeyEvent(focusOwner, id, when, modifiers,
keyCode, keyChar, keyLocation);
AWTAccessor.getKeyEventAccessor().setExtendedKeyCode(keyEvent,
ExtendedKeyCodes.getExtendedKeyCodeForChar(keyChar));
postEvent(keyEvent);
} }
// ---- UTILITY METHODS ---- // // ---- UTILITY METHODS ---- //
@ -1152,8 +1162,9 @@ public class LWWindowPeer
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) { if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
focusLog.fine("requesting native focus to the owner " + owner); focusLog.fine("requesting native focus to the owner " + owner);
} }
LWWindowPeer currentActivePeer = (currentActive != null ? LWWindowPeer currentActivePeer = currentActive == null ? null :
(LWWindowPeer)currentActive.getPeer() : null); (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(
currentActive);
// Ensure the opposite is natively active and suppress sending events. // Ensure the opposite is natively active and suppress sending events.
if (currentActivePeer != null && currentActivePeer.platformWindow.isActive()) { if (currentActivePeer != null && currentActivePeer.platformWindow.isActive()) {
@ -1265,7 +1276,8 @@ public class LWWindowPeer
while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) { while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) {
owner = owner.getOwner(); owner = owner.getOwner();
} }
return owner != null ? (LWWindowPeer)owner.getPeer() : null; return owner == null ? null :
(LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(owner);
} }
/** /**
@ -1284,11 +1296,13 @@ public class LWWindowPeer
} }
} }
@Override
public void enterFullScreenMode() { public void enterFullScreenMode() {
platformWindow.enterFullScreenMode(); platformWindow.enterFullScreenMode();
updateSecurityWarningVisibility(); updateSecurityWarningVisibility();
} }
@Override
public void exitFullScreenMode() { public void exitFullScreenMode() {
platformWindow.exitFullScreenMode(); platformWindow.exitFullScreenMode();
updateSecurityWarningVisibility(); updateSecurityWarningVisibility();

View File

@ -26,9 +26,11 @@
package sun.lwawt.macosx; package sun.lwawt.macosx;
import java.awt.*; import java.awt.*;
import java.awt.peer.MenuItemPeer;
import java.awt.peer.MenuPeer; import java.awt.peer.MenuPeer;
public class CMenu extends CMenuItem implements MenuPeer { public class CMenu extends CMenuItem implements MenuPeer {
public CMenu(Menu target) { public CMenu(Menu target) {
super(target); super(target);
} }
@ -40,6 +42,20 @@ public class CMenu extends CMenuItem implements MenuPeer {
setEnabled(target.isEnabled()); setEnabled(target.isEnabled());
} }
@Override
public final void setEnabled(final boolean b) {
super.setEnabled(b);
final Menu target = (Menu) getTarget();
final int count = target.getItemCount();
for (int i = 0; i < count; ++i) {
MenuItem item = target.getItem(i);
MenuItemPeer p = (MenuItemPeer) LWCToolkit.targetToPeer(item);
if (p != null) {
p.setEnabled(b && item.isEnabled());
}
}
}
@Override @Override
protected long createModel() { protected long createModel() {
CMenuComponent parent = (CMenuComponent) CMenuComponent parent = (CMenuComponent)

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