Merge
This commit is contained in:
commit
c677e3600a
@ -15,3 +15,4 @@ bb1ef4ee3d2c8cbf43a37d372325a7952be590b9 jdk7-b33
|
||||
cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38
|
||||
ab523b49de1fc73fefe6855ce1e0349bdbd7af29 jdk7-b39
|
||||
44be42de6693063fb191989bf0e188de2fa51e7c jdk7-b40
|
||||
541bdc5ad32fc33255944d0a044ad992f3d915e8 jdk7-b41
|
||||
|
@ -839,7 +839,7 @@
|
||||
<blockquote>
|
||||
All OpenJDK builds require access to least Ant 1.6.5.
|
||||
The Ant tool is available from the
|
||||
<a href="http://ant.apache.org/antlibs/bindownload.cgi" target="_blank">
|
||||
<a href="http://ant.apache.org" target="_blank">
|
||||
Ant download site</a>.
|
||||
You should always make sure <tt>ant</tt> is in your PATH, and
|
||||
on Windows you may also need to set
|
||||
|
@ -15,3 +15,4 @@ ef6af34d75a7b44e77083f1d4ee47631fa09d3b4 jdk7-b31
|
||||
08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38
|
||||
55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39
|
||||
184e21992f47a8d730df1adc5b21a108f3125489 jdk7-b40
|
||||
c90eeda9594ed2983403e2049aed8d503126c62e jdk7-b41
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -15,3 +15,4 @@ e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36
|
||||
d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
|
||||
49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
|
||||
81a0cbe3b28460ce836109934ece03db7afaf9cc jdk7-b40
|
||||
f9d938ede1960d18cb7cf23c645b026519c1a678 jdk7-b41
|
||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2008
|
||||
|
||||
HS_MAJOR_VER=14
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=08
|
||||
HS_BUILD_NUMBER=09
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=7
|
||||
|
@ -200,29 +200,6 @@ BUILD_WIN_SA = 0
|
||||
checkSA::
|
||||
@echo Not building SA: ARCH = ia64
|
||||
|
||||
!elseif exist("$(MSVCDIR)\PlatformSDK\Include\dbgeng.h")
|
||||
# These don't have to be set because the default
|
||||
# setting of INCLUDE and LIB already contain the needed dirs.
|
||||
SA_INCLUDE =
|
||||
SA_LIB =
|
||||
|
||||
!elseif exist("$(SYSTEMROOT)\..\Program Files\Microsoft SDK\include\dbgeng.h")
|
||||
# These don't have to be set because the default
|
||||
# setting of INCLUDE and LIB already contain the needed dirs.
|
||||
SA_INCLUDE =
|
||||
SA_LIB =
|
||||
|
||||
!else
|
||||
checkSA::
|
||||
@echo .
|
||||
@echo ERROR: Can't build SA because dbgeng.h does not exist here:
|
||||
@echo $(MSVCDIR)\PlatformSDK\Include\dbgeng.h
|
||||
@echo nor here:
|
||||
@echo $(SYSTEMROOT)\..\Program Files\Microsoft SDK\include\dbgeng.h
|
||||
@echo You must use Vis. Studio .Net 2003 on Win 32, and you must
|
||||
@echo have the Microsoft SDK installed on Win amd64.
|
||||
@echo You can disable building of SA by specifying BUILD_WIN_SA = 0
|
||||
@echo . && false
|
||||
!endif # ! "$(BUILD_WIN_SA)" != "1"
|
||||
|
||||
#########################################################################
|
||||
|
@ -119,7 +119,7 @@ endif
|
||||
# we want to release it. If we build it here,
|
||||
# the SDK makefiles will copy it over and put it into
|
||||
# the created image.
|
||||
BUILD_WIN_SA = 0
|
||||
BUILD_WIN_SA = 1
|
||||
ifneq ($(ALT_BUILD_WIN_SA),)
|
||||
BUILD_WIN_SA = $(ALT_BUILD_WIN_SA)
|
||||
endif
|
||||
|
@ -49,6 +49,9 @@ SA_PROPERTIES = $(SA_CLASSDIR)\sa.properties
|
||||
|
||||
default:: $(GENERATED)\sa-jdi.jar
|
||||
|
||||
# Remove the space between $(SA_BUILD_VERSION_PROP) and > below as it adds a white space
|
||||
# at the end of SA version string and causes a version mismatch with the target VM version.
|
||||
|
||||
$(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
|
||||
@if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR)
|
||||
@echo ...Building sa-jdi.jar
|
||||
@ -56,15 +59,15 @@ $(GENERATED)\sa-jdi.jar: $(AGENT_FILES1:/=\) $(AGENT_FILES2:/=\)
|
||||
@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES1:/=\)
|
||||
@$(COMPILE_JAVAC) -source 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -g -d $(SA_CLASSDIR) $(AGENT_FILES2:/=\)
|
||||
$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
|
||||
$(QUIETLY) echo $(SA_BUILD_VERSION_PROP) > $(SA_PROPERTIES)
|
||||
$(RUN_JAR) cf $@ -C saclasses .
|
||||
$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector
|
||||
$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
|
||||
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
|
||||
$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql
|
||||
$(QUIETLY) mkdir -p $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
|
||||
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/*
|
||||
$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/
|
||||
$(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/
|
||||
$(QUIETLY) rm -rf $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
|
||||
$(QUIETLY) mkdir $(SA_CLASSDIR)\sun\jvm\hotspot\ui\resources
|
||||
$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
|
||||
$(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)
|
||||
$(RUN_JAR) cf $@ -C saclasses .
|
||||
$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector
|
||||
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal
|
||||
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
|
||||
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.ia64.IA64ThreadContext
|
||||
@ -93,7 +96,7 @@ SA_LINK_FLAGS = bufferoverflowU.lib
|
||||
SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
!endif
|
||||
!if "$(MT)" != ""
|
||||
SA_LINK_FLAGS = /manifest $(SA_LINK_FLAGS)
|
||||
SA_LINK_FLAGS = /manifest $(SA_LINK_FLAGS)
|
||||
!endif
|
||||
SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp
|
||||
SA_LFLAGS = $(SA_LINK_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE)
|
||||
|
@ -2085,7 +2085,7 @@ void TemplateTable::jvmti_post_field_access(Register Rcache,
|
||||
} else {
|
||||
if (has_tos) {
|
||||
// save object pointer before call_VM() clobbers it
|
||||
__ mov(Otos_i, Lscratch);
|
||||
__ push_ptr(Otos_i); // put object on tos where GC wants it.
|
||||
} else {
|
||||
// Load top of stack (do not pop the value off the stack);
|
||||
__ ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(0), Otos_i);
|
||||
@ -2097,7 +2097,7 @@ void TemplateTable::jvmti_post_field_access(Register Rcache,
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access),
|
||||
Otos_i, Rcache);
|
||||
if (!is_static && has_tos) {
|
||||
__ mov(Lscratch, Otos_i); // restore object pointer
|
||||
__ pop_ptr(Otos_i); // restore object pointer
|
||||
__ verify_oop(Otos_i);
|
||||
}
|
||||
__ get_cache_and_index_at_bcp(Rcache, index, 1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -2272,7 +2272,9 @@ void os::free_memory(char *addr, size_t bytes) {
|
||||
uncommit_memory(addr, bytes);
|
||||
}
|
||||
|
||||
void os::numa_make_global(char *addr, size_t bytes) { }
|
||||
void os::numa_make_global(char *addr, size_t bytes) {
|
||||
Linux::numa_interleave_memory(addr, bytes);
|
||||
}
|
||||
|
||||
void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
|
||||
Linux::numa_tonode_memory(addr, bytes, lgrp_hint);
|
||||
@ -2314,7 +2316,7 @@ char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info
|
||||
extern "C" void numa_warn(int number, char *where, ...) { }
|
||||
extern "C" void numa_error(char *where) { }
|
||||
|
||||
void os::Linux::libnuma_init() {
|
||||
bool os::Linux::libnuma_init() {
|
||||
// sched_getcpu() should be in libc.
|
||||
set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
|
||||
dlsym(RTLD_DEFAULT, "sched_getcpu")));
|
||||
@ -2330,31 +2332,51 @@ void os::Linux::libnuma_init() {
|
||||
dlsym(handle, "numa_available")));
|
||||
set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t,
|
||||
dlsym(handle, "numa_tonode_memory")));
|
||||
set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
|
||||
dlsym(handle, "numa_interleave_memory")));
|
||||
|
||||
|
||||
if (numa_available() != -1) {
|
||||
set_numa_all_nodes((unsigned long*)dlsym(handle, "numa_all_nodes"));
|
||||
// Create a cpu -> node mapping
|
||||
_cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true);
|
||||
rebuild_cpu_to_node_map();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id.
|
||||
// The table is later used in get_node_by_cpu().
|
||||
void os::Linux::rebuild_cpu_to_node_map() {
|
||||
int cpu_num = os::active_processor_count();
|
||||
const size_t NCPUS = 32768; // Since the buffer size computation is very obscure
|
||||
// in libnuma (possible values are starting from 16,
|
||||
// and continuing up with every other power of 2, but less
|
||||
// than the maximum number of CPUs supported by kernel), and
|
||||
// is a subject to change (in libnuma version 2 the requirements
|
||||
// are more reasonable) we'll just hardcode the number they use
|
||||
// in the library.
|
||||
const size_t BitsPerCLong = sizeof(long) * CHAR_BIT;
|
||||
|
||||
size_t cpu_num = os::active_processor_count();
|
||||
size_t cpu_map_size = NCPUS / BitsPerCLong;
|
||||
size_t cpu_map_valid_size =
|
||||
MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
|
||||
|
||||
cpu_to_node()->clear();
|
||||
cpu_to_node()->at_grow(cpu_num - 1);
|
||||
int node_num = numa_get_groups_num();
|
||||
int cpu_map_size = (cpu_num + BitsPerLong - 1) / BitsPerLong;
|
||||
size_t node_num = numa_get_groups_num();
|
||||
|
||||
unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size);
|
||||
for (int i = 0; i < node_num; i++) {
|
||||
for (size_t i = 0; i < node_num; i++) {
|
||||
if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
|
||||
for (int j = 0; j < cpu_map_size; j++) {
|
||||
for (size_t j = 0; j < cpu_map_valid_size; j++) {
|
||||
if (cpu_map[j] != 0) {
|
||||
for (int k = 0; k < BitsPerLong; k++) {
|
||||
for (size_t k = 0; k < BitsPerCLong; k++) {
|
||||
if (cpu_map[j] & (1UL << k)) {
|
||||
cpu_to_node()->at_put(j * BitsPerLong + k, i);
|
||||
cpu_to_node()->at_put(j * BitsPerCLong + k, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2377,7 +2399,8 @@ os::Linux::numa_node_to_cpus_func_t os::Linux::_numa_node_to_cpus;
|
||||
os::Linux::numa_max_node_func_t os::Linux::_numa_max_node;
|
||||
os::Linux::numa_available_func_t os::Linux::_numa_available;
|
||||
os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory;
|
||||
|
||||
os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
|
||||
unsigned long* os::Linux::_numa_all_nodes;
|
||||
|
||||
bool os::uncommit_memory(char* addr, size_t size) {
|
||||
return ::mmap(addr, size,
|
||||
@ -3695,7 +3718,17 @@ jint os::init_2(void)
|
||||
}
|
||||
|
||||
if (UseNUMA) {
|
||||
Linux::libnuma_init();
|
||||
if (!Linux::libnuma_init()) {
|
||||
UseNUMA = false;
|
||||
} else {
|
||||
if ((Linux::numa_max_node() < 1)) {
|
||||
// There's only one node(they start from 0), disable NUMA.
|
||||
UseNUMA = false;
|
||||
}
|
||||
}
|
||||
if (!UseNUMA && ForceNUMA) {
|
||||
UseNUMA = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (MaxFDLimit) {
|
||||
|
@ -146,7 +146,7 @@ class Linux {
|
||||
static bool is_floating_stack() { return _is_floating_stack; }
|
||||
|
||||
static void libpthread_init();
|
||||
static void libnuma_init();
|
||||
static bool libnuma_init();
|
||||
|
||||
// Minimum stack size a thread can be created with (allowing
|
||||
// the VM to completely create the thread and enter user code)
|
||||
@ -240,20 +240,23 @@ private:
|
||||
typedef int (*numa_max_node_func_t)(void);
|
||||
typedef int (*numa_available_func_t)(void);
|
||||
typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);
|
||||
|
||||
typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);
|
||||
|
||||
static sched_getcpu_func_t _sched_getcpu;
|
||||
static numa_node_to_cpus_func_t _numa_node_to_cpus;
|
||||
static numa_max_node_func_t _numa_max_node;
|
||||
static numa_available_func_t _numa_available;
|
||||
static numa_tonode_memory_func_t _numa_tonode_memory;
|
||||
static numa_interleave_memory_func_t _numa_interleave_memory;
|
||||
static unsigned long* _numa_all_nodes;
|
||||
|
||||
static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; }
|
||||
static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; }
|
||||
static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; }
|
||||
static void set_numa_available(numa_available_func_t func) { _numa_available = func; }
|
||||
static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; }
|
||||
|
||||
static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; }
|
||||
static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }
|
||||
public:
|
||||
static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
|
||||
static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
|
||||
@ -264,6 +267,11 @@ public:
|
||||
static int numa_tonode_memory(void *start, size_t size, int node) {
|
||||
return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1;
|
||||
}
|
||||
static void numa_interleave_memory(void *start, size_t size) {
|
||||
if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) {
|
||||
_numa_interleave_memory(start, size, _numa_all_nodes);
|
||||
}
|
||||
}
|
||||
static int get_node_by_cpu(int cpu_id);
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -4638,7 +4638,7 @@ void os::Solaris::synchronization_init() {
|
||||
}
|
||||
}
|
||||
|
||||
void os::Solaris::liblgrp_init() {
|
||||
bool os::Solaris::liblgrp_init() {
|
||||
void *handle = dlopen("liblgrp.so.1", RTLD_LAZY);
|
||||
if (handle != NULL) {
|
||||
os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home")));
|
||||
@ -4653,9 +4653,9 @@ void os::Solaris::liblgrp_init() {
|
||||
|
||||
lgrp_cookie_t c = lgrp_init(LGRP_VIEW_CALLER);
|
||||
set_lgrp_cookie(c);
|
||||
} else {
|
||||
warning("your OS does not support NUMA");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void os::Solaris::misc_sym_init() {
|
||||
@ -4824,9 +4824,25 @@ jint os::init_2(void) {
|
||||
vm_page_size()));
|
||||
|
||||
Solaris::libthread_init();
|
||||
|
||||
if (UseNUMA) {
|
||||
Solaris::liblgrp_init();
|
||||
if (!Solaris::liblgrp_init()) {
|
||||
UseNUMA = false;
|
||||
} else {
|
||||
size_t lgrp_limit = os::numa_get_groups_num();
|
||||
int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit);
|
||||
size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
|
||||
FREE_C_HEAP_ARRAY(int, lgrp_ids);
|
||||
if (lgrp_num < 2) {
|
||||
// There's only one locality group, disable NUMA.
|
||||
UseNUMA = false;
|
||||
}
|
||||
}
|
||||
if (!UseNUMA && ForceNUMA) {
|
||||
UseNUMA = true;
|
||||
}
|
||||
}
|
||||
|
||||
Solaris::misc_sym_init();
|
||||
Solaris::signal_sets_init();
|
||||
Solaris::init_signal_mem();
|
||||
|
@ -176,7 +176,7 @@ class Solaris {
|
||||
public:
|
||||
static void libthread_init();
|
||||
static void synchronization_init();
|
||||
static void liblgrp_init();
|
||||
static bool liblgrp_init();
|
||||
// Load miscellaneous symbols.
|
||||
static void misc_sym_init();
|
||||
// This boolean allows users to forward their own non-matching signals
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -2217,15 +2217,10 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
// We only expect null pointers in the stubs (vtable)
|
||||
// the rest are checked explicitly now.
|
||||
//
|
||||
CodeBlob* cb = CodeCache::find_blob(pc);
|
||||
if (cb != NULL) {
|
||||
if (VtableStubs::stub_containing(pc) != NULL) {
|
||||
if (((uintptr_t)addr) < os::vm_page_size() ) {
|
||||
// an access to the first page of VM--assume it is a null pointer
|
||||
return Handle_Exception(exceptionInfo,
|
||||
SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL));
|
||||
}
|
||||
}
|
||||
if (((uintptr_t)addr) < os::vm_page_size() ) {
|
||||
// an access to the first page of VM--assume it is a null pointer
|
||||
address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
|
||||
if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
|
||||
}
|
||||
}
|
||||
} // in_java
|
||||
@ -2241,9 +2236,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
// Windows 98 reports faulting addresses incorrectly
|
||||
if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
|
||||
!os::win32::is_nt()) {
|
||||
|
||||
return Handle_Exception(exceptionInfo,
|
||||
SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL));
|
||||
address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
|
||||
if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
|
||||
}
|
||||
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
|
||||
exceptionInfo->ContextRecord);
|
||||
@ -3353,6 +3347,10 @@ jint os::init_2(void) {
|
||||
// initialize thread priority policy
|
||||
prio_init();
|
||||
|
||||
if (UseNUMA && !ForceNUMA) {
|
||||
UseNUMA = false; // Currently unsupported.
|
||||
}
|
||||
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
// Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
//
|
||||
// This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -676,21 +676,6 @@ GraphBuilder::ScopeData::ScopeData(ScopeData* parent)
|
||||
}
|
||||
|
||||
|
||||
void GraphBuilder::kill_field(ciField* field) {
|
||||
if (UseLocalValueNumbering) {
|
||||
vmap()->kill_field(field);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GraphBuilder::kill_array(Value value) {
|
||||
if (UseLocalValueNumbering) {
|
||||
vmap()->kill_array(value->type());
|
||||
}
|
||||
_memory->store_value(value);
|
||||
}
|
||||
|
||||
|
||||
void GraphBuilder::kill_all() {
|
||||
if (UseLocalValueNumbering) {
|
||||
vmap()->kill_all();
|
||||
@ -987,8 +972,8 @@ void GraphBuilder::store_indexed(BasicType type) {
|
||||
length = append(new ArrayLength(array, lock_stack()));
|
||||
}
|
||||
StoreIndexed* result = new StoreIndexed(array, index, length, type, value, lock_stack());
|
||||
kill_array(value); // invalidate all CSEs that are memory accesses of the same type
|
||||
append(result);
|
||||
_memory->store_value(value);
|
||||
}
|
||||
|
||||
|
||||
@ -1478,9 +1463,6 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
case Bytecodes::_putstatic:
|
||||
{ Value val = pop(type);
|
||||
append(new StoreField(append(obj), offset, field, val, true, lock_stack(), state_copy, is_loaded, is_initialized));
|
||||
if (UseLocalValueNumbering) {
|
||||
vmap()->kill_field(field); // invalidate all CSEs that are memory accesses
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Bytecodes::_getfield :
|
||||
@ -1503,7 +1485,6 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
if (is_loaded) store = _memory->store(store);
|
||||
if (store != NULL) {
|
||||
append(store);
|
||||
kill_field(field); // invalidate all CSEs that are accesses of this field
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1900,6 +1881,8 @@ Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
|
||||
assert(i2->bci() != -1, "should already be linked");
|
||||
return i2;
|
||||
}
|
||||
ValueNumberingEffects vne(vmap());
|
||||
i1->visit(&vne);
|
||||
}
|
||||
|
||||
if (i1->as_Phi() == NULL && i1->as_Local() == NULL) {
|
||||
@ -1926,14 +1909,8 @@ Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
|
||||
assert(_last == i1, "adjust code below");
|
||||
StateSplit* s = i1->as_StateSplit();
|
||||
if (s != NULL && i1->as_BlockEnd() == NULL) {
|
||||
// Continue CSE across certain intrinsics
|
||||
Intrinsic* intrinsic = s->as_Intrinsic();
|
||||
if (UseLocalValueNumbering) {
|
||||
if (intrinsic == NULL || !intrinsic->preserves_state()) {
|
||||
vmap()->kill_all(); // for now, hopefully we need this only for calls eventually
|
||||
}
|
||||
}
|
||||
if (EliminateFieldAccess) {
|
||||
Intrinsic* intrinsic = s->as_Intrinsic();
|
||||
if (s->as_Invoke() != NULL || (intrinsic && !intrinsic->preserves_state())) {
|
||||
_memory->kill();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -283,8 +283,6 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC {
|
||||
Dependencies* dependency_recorder() const; // = compilation()->dependencies()
|
||||
bool direct_compare(ciKlass* k);
|
||||
|
||||
void kill_field(ciField* field);
|
||||
void kill_array(Value value);
|
||||
void kill_all();
|
||||
|
||||
ValueStack* lock_stack();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -133,53 +133,77 @@ class ValueNumberingVisitor: public InstructionVisitor {
|
||||
virtual void kill_array(ValueType* type) = 0;
|
||||
|
||||
// visitor functions
|
||||
void do_StoreField (StoreField* x) { kill_field(x->field()); };
|
||||
void do_StoreIndexed (StoreIndexed* x) { kill_array(x->type()); };
|
||||
void do_MonitorEnter (MonitorEnter* x) { kill_memory(); };
|
||||
void do_MonitorExit (MonitorExit* x) { kill_memory(); };
|
||||
void do_Invoke (Invoke* x) { kill_memory(); };
|
||||
void do_UnsafePutRaw (UnsafePutRaw* x) { kill_memory(); };
|
||||
void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); };
|
||||
void do_Intrinsic (Intrinsic* x) { if (!x->preserves_state()) kill_memory(); };
|
||||
void do_StoreField (StoreField* x) {
|
||||
if (!x->is_initialized()) {
|
||||
kill_memory();
|
||||
} else {
|
||||
kill_field(x->field());
|
||||
}
|
||||
}
|
||||
void do_StoreIndexed (StoreIndexed* x) { kill_array(x->type()); }
|
||||
void do_MonitorEnter (MonitorEnter* x) { kill_memory(); }
|
||||
void do_MonitorExit (MonitorExit* x) { kill_memory(); }
|
||||
void do_Invoke (Invoke* x) { kill_memory(); }
|
||||
void do_UnsafePutRaw (UnsafePutRaw* x) { kill_memory(); }
|
||||
void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); }
|
||||
void do_Intrinsic (Intrinsic* x) { if (!x->preserves_state()) kill_memory(); }
|
||||
|
||||
void do_Phi (Phi* x) { /* nothing to do */ };
|
||||
void do_Local (Local* x) { /* nothing to do */ };
|
||||
void do_Constant (Constant* x) { /* nothing to do */ };
|
||||
void do_LoadField (LoadField* x) { /* nothing to do */ };
|
||||
void do_ArrayLength (ArrayLength* x) { /* nothing to do */ };
|
||||
void do_LoadIndexed (LoadIndexed* x) { /* nothing to do */ };
|
||||
void do_NegateOp (NegateOp* x) { /* nothing to do */ };
|
||||
void do_ArithmeticOp (ArithmeticOp* x) { /* nothing to do */ };
|
||||
void do_ShiftOp (ShiftOp* x) { /* nothing to do */ };
|
||||
void do_LogicOp (LogicOp* x) { /* nothing to do */ };
|
||||
void do_CompareOp (CompareOp* x) { /* nothing to do */ };
|
||||
void do_IfOp (IfOp* x) { /* nothing to do */ };
|
||||
void do_Convert (Convert* x) { /* nothing to do */ };
|
||||
void do_NullCheck (NullCheck* x) { /* nothing to do */ };
|
||||
void do_NewInstance (NewInstance* x) { /* nothing to do */ };
|
||||
void do_NewTypeArray (NewTypeArray* x) { /* nothing to do */ };
|
||||
void do_NewObjectArray (NewObjectArray* x) { /* nothing to do */ };
|
||||
void do_NewMultiArray (NewMultiArray* x) { /* nothing to do */ };
|
||||
void do_CheckCast (CheckCast* x) { /* nothing to do */ };
|
||||
void do_InstanceOf (InstanceOf* x) { /* nothing to do */ };
|
||||
void do_BlockBegin (BlockBegin* x) { /* nothing to do */ };
|
||||
void do_Goto (Goto* x) { /* nothing to do */ };
|
||||
void do_If (If* x) { /* nothing to do */ };
|
||||
void do_IfInstanceOf (IfInstanceOf* x) { /* nothing to do */ };
|
||||
void do_TableSwitch (TableSwitch* x) { /* nothing to do */ };
|
||||
void do_LookupSwitch (LookupSwitch* x) { /* nothing to do */ };
|
||||
void do_Return (Return* x) { /* nothing to do */ };
|
||||
void do_Throw (Throw* x) { /* nothing to do */ };
|
||||
void do_Base (Base* x) { /* nothing to do */ };
|
||||
void do_OsrEntry (OsrEntry* x) { /* nothing to do */ };
|
||||
void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ };
|
||||
void do_RoundFP (RoundFP* x) { /* nothing to do */ };
|
||||
void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ };
|
||||
void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ };
|
||||
void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ };
|
||||
void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ };
|
||||
void do_ProfileCall (ProfileCall* x) { /* nothing to do */ };
|
||||
void do_ProfileCounter (ProfileCounter* x) { /* nothing to do */ };
|
||||
void do_Phi (Phi* x) { /* nothing to do */ }
|
||||
void do_Local (Local* x) { /* nothing to do */ }
|
||||
void do_Constant (Constant* x) { /* nothing to do */ }
|
||||
void do_LoadField (LoadField* x) {
|
||||
if (!x->is_initialized()) {
|
||||
kill_memory();
|
||||
}
|
||||
}
|
||||
void do_ArrayLength (ArrayLength* x) { /* nothing to do */ }
|
||||
void do_LoadIndexed (LoadIndexed* x) { /* nothing to do */ }
|
||||
void do_NegateOp (NegateOp* x) { /* nothing to do */ }
|
||||
void do_ArithmeticOp (ArithmeticOp* x) { /* nothing to do */ }
|
||||
void do_ShiftOp (ShiftOp* x) { /* nothing to do */ }
|
||||
void do_LogicOp (LogicOp* x) { /* nothing to do */ }
|
||||
void do_CompareOp (CompareOp* x) { /* nothing to do */ }
|
||||
void do_IfOp (IfOp* x) { /* nothing to do */ }
|
||||
void do_Convert (Convert* x) { /* nothing to do */ }
|
||||
void do_NullCheck (NullCheck* x) { /* nothing to do */ }
|
||||
void do_NewInstance (NewInstance* x) { /* nothing to do */ }
|
||||
void do_NewTypeArray (NewTypeArray* x) { /* nothing to do */ }
|
||||
void do_NewObjectArray (NewObjectArray* x) { /* nothing to do */ }
|
||||
void do_NewMultiArray (NewMultiArray* x) { /* nothing to do */ }
|
||||
void do_CheckCast (CheckCast* x) { /* nothing to do */ }
|
||||
void do_InstanceOf (InstanceOf* x) { /* nothing to do */ }
|
||||
void do_BlockBegin (BlockBegin* x) { /* nothing to do */ }
|
||||
void do_Goto (Goto* x) { /* nothing to do */ }
|
||||
void do_If (If* x) { /* nothing to do */ }
|
||||
void do_IfInstanceOf (IfInstanceOf* x) { /* nothing to do */ }
|
||||
void do_TableSwitch (TableSwitch* x) { /* nothing to do */ }
|
||||
void do_LookupSwitch (LookupSwitch* x) { /* nothing to do */ }
|
||||
void do_Return (Return* x) { /* nothing to do */ }
|
||||
void do_Throw (Throw* x) { /* nothing to do */ }
|
||||
void do_Base (Base* x) { /* nothing to do */ }
|
||||
void do_OsrEntry (OsrEntry* x) { /* nothing to do */ }
|
||||
void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }
|
||||
void do_RoundFP (RoundFP* x) { /* nothing to do */ }
|
||||
void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ }
|
||||
void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }
|
||||
void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ }
|
||||
void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }
|
||||
void do_ProfileCall (ProfileCall* x) { /* nothing to do */ }
|
||||
void do_ProfileCounter (ProfileCounter* x) { /* nothing to do */ }
|
||||
};
|
||||
|
||||
|
||||
class ValueNumberingEffects: public ValueNumberingVisitor {
|
||||
private:
|
||||
ValueMap* _map;
|
||||
|
||||
public:
|
||||
// implementation for abstract methods of ValueNumberingVisitor
|
||||
void kill_memory() { _map->kill_memory(); }
|
||||
void kill_field(ciField* field) { _map->kill_field(field); }
|
||||
void kill_array(ValueType* type) { _map->kill_array(type); }
|
||||
|
||||
ValueNumberingEffects(ValueMap* map): _map(map) {}
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -325,24 +325,30 @@ class Par_PushOrMarkClosure: public OopClosure {
|
||||
// For objects in CMS generation, this closure marks
|
||||
// given objects (transitively) as being reachable/live.
|
||||
// This is currently used during the (weak) reference object
|
||||
// processing phase of the CMS final checkpoint step.
|
||||
// processing phase of the CMS final checkpoint step, as
|
||||
// well as during the concurrent precleaning of the discovered
|
||||
// reference lists.
|
||||
class CMSKeepAliveClosure: public OopClosure {
|
||||
private:
|
||||
CMSCollector* _collector;
|
||||
const MemRegion _span;
|
||||
CMSMarkStack* _mark_stack;
|
||||
CMSBitMap* _bit_map;
|
||||
bool _concurrent_precleaning;
|
||||
protected:
|
||||
DO_OOP_WORK_DEFN
|
||||
public:
|
||||
CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,
|
||||
CMSBitMap* bit_map, CMSMarkStack* mark_stack):
|
||||
CMSBitMap* bit_map, CMSMarkStack* mark_stack,
|
||||
bool cpc):
|
||||
_collector(collector),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_mark_stack(mark_stack) {
|
||||
_mark_stack(mark_stack),
|
||||
_concurrent_precleaning(cpc) {
|
||||
assert(!_span.is_empty(), "Empty span could spell trouble");
|
||||
}
|
||||
bool concurrent_precleaning() const { return _concurrent_precleaning; }
|
||||
virtual void do_oop(oop* p);
|
||||
virtual void do_oop(narrowOop* p);
|
||||
inline void do_oop_nv(oop* p) { CMSKeepAliveClosure::do_oop_work(p); }
|
||||
|
@ -538,6 +538,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
|
||||
_survivor_chunk_capacity(0), // -- ditto --
|
||||
_survivor_chunk_index(0), // -- ditto --
|
||||
_ser_pmc_preclean_ovflw(0),
|
||||
_ser_kac_preclean_ovflw(0),
|
||||
_ser_pmc_remark_ovflw(0),
|
||||
_par_pmc_remark_ovflw(0),
|
||||
_ser_kac_ovflw(0),
|
||||
@ -1960,6 +1961,7 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
|
||||
|
||||
ref_processor()->set_enqueuing_is_done(false);
|
||||
ref_processor()->enable_discovery();
|
||||
ref_processor()->setup_policy(clear_all_soft_refs);
|
||||
// If an asynchronous collection finishes, the _modUnionTable is
|
||||
// all clear. If we are assuming the collection from an asynchronous
|
||||
// collection, clear the _modUnionTable.
|
||||
@ -2383,6 +2385,9 @@ void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
|
||||
Universe::verify(true);
|
||||
}
|
||||
|
||||
// Snapshot the soft reference policy to be used in this collection cycle.
|
||||
ref_processor()->setup_policy(clear_all_soft_refs);
|
||||
|
||||
bool init_mark_was_synchronous = false; // until proven otherwise
|
||||
while (_collectorState != Idling) {
|
||||
if (TraceCMSState) {
|
||||
@ -4388,10 +4393,10 @@ size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
|
||||
CMSPrecleanRefsYieldClosure yield_cl(this);
|
||||
assert(rp->span().equals(_span), "Spans should be equal");
|
||||
CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
|
||||
&_markStack);
|
||||
&_markStack, true /* preclean */);
|
||||
CMSDrainMarkingStackClosure complete_trace(this,
|
||||
_span, &_markBitMap, &_markStack,
|
||||
&keep_alive);
|
||||
_span, &_markBitMap, &_markStack,
|
||||
&keep_alive, true /* preclean */);
|
||||
|
||||
// We don't want this step to interfere with a young
|
||||
// collection because we don't want to take CPU
|
||||
@ -4590,11 +4595,11 @@ size_t CMSCollector::preclean_mod_union_table(
|
||||
if (!dirtyRegion.is_empty()) {
|
||||
assert(numDirtyCards > 0, "consistency check");
|
||||
HeapWord* stop_point = NULL;
|
||||
stopTimer();
|
||||
CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
|
||||
bitMapLock());
|
||||
startTimer();
|
||||
{
|
||||
stopTimer();
|
||||
CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
|
||||
bitMapLock());
|
||||
startTimer();
|
||||
verify_work_stacks_empty();
|
||||
verify_overflow_empty();
|
||||
sample_eden();
|
||||
@ -4611,10 +4616,6 @@ size_t CMSCollector::preclean_mod_union_table(
|
||||
assert((CMSPermGenPrecleaningEnabled && (gen == _permGen)) ||
|
||||
(_collectorState == AbortablePreclean && should_abort_preclean()),
|
||||
"Unparsable objects should only be in perm gen.");
|
||||
|
||||
stopTimer();
|
||||
CMSTokenSyncWithLocks ts(true, bitMapLock());
|
||||
startTimer();
|
||||
_modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end()));
|
||||
if (should_abort_preclean()) {
|
||||
break; // out of preclean loop
|
||||
@ -4852,17 +4853,19 @@ void CMSCollector::checkpointRootsFinalWork(bool asynch,
|
||||
// recurrence of that condition.
|
||||
assert(_markStack.isEmpty(), "No grey objects");
|
||||
size_t ser_ovflw = _ser_pmc_remark_ovflw + _ser_pmc_preclean_ovflw +
|
||||
_ser_kac_ovflw;
|
||||
_ser_kac_ovflw + _ser_kac_preclean_ovflw;
|
||||
if (ser_ovflw > 0) {
|
||||
if (PrintCMSStatistics != 0) {
|
||||
gclog_or_tty->print_cr("Marking stack overflow (benign) "
|
||||
"(pmc_pc="SIZE_FORMAT", pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT")",
|
||||
"(pmc_pc="SIZE_FORMAT", pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT
|
||||
", kac_preclean="SIZE_FORMAT")",
|
||||
_ser_pmc_preclean_ovflw, _ser_pmc_remark_ovflw,
|
||||
_ser_kac_ovflw);
|
||||
_ser_kac_ovflw, _ser_kac_preclean_ovflw);
|
||||
}
|
||||
_markStack.expand();
|
||||
_ser_pmc_remark_ovflw = 0;
|
||||
_ser_pmc_preclean_ovflw = 0;
|
||||
_ser_kac_preclean_ovflw = 0;
|
||||
_ser_kac_ovflw = 0;
|
||||
}
|
||||
if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
|
||||
@ -5675,40 +5678,29 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
|
||||
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
ReferencePolicy* soft_ref_policy;
|
||||
|
||||
assert(!ref_processor()->enqueuing_is_done(), "Enqueuing should not be complete");
|
||||
// Process weak references.
|
||||
if (clear_all_soft_refs) {
|
||||
soft_ref_policy = new AlwaysClearPolicy();
|
||||
} else {
|
||||
#ifdef COMPILER2
|
||||
soft_ref_policy = new LRUMaxHeapPolicy();
|
||||
#else
|
||||
soft_ref_policy = new LRUCurrentHeapPolicy();
|
||||
#endif // COMPILER2
|
||||
}
|
||||
verify_work_stacks_empty();
|
||||
|
||||
ReferenceProcessor* rp = ref_processor();
|
||||
assert(rp->span().equals(_span), "Spans should be equal");
|
||||
assert(!rp->enqueuing_is_done(), "Enqueuing should not be complete");
|
||||
// Process weak references.
|
||||
rp->setup_policy(clear_all_soft_refs);
|
||||
verify_work_stacks_empty();
|
||||
|
||||
CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap,
|
||||
&_markStack);
|
||||
&_markStack, false /* !preclean */);
|
||||
CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this,
|
||||
_span, &_markBitMap, &_markStack,
|
||||
&cmsKeepAliveClosure);
|
||||
&cmsKeepAliveClosure, false /* !preclean */);
|
||||
{
|
||||
TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty);
|
||||
if (rp->processing_is_mt()) {
|
||||
CMSRefProcTaskExecutor task_executor(*this);
|
||||
rp->process_discovered_references(soft_ref_policy,
|
||||
&_is_alive_closure,
|
||||
rp->process_discovered_references(&_is_alive_closure,
|
||||
&cmsKeepAliveClosure,
|
||||
&cmsDrainMarkingStackClosure,
|
||||
&task_executor);
|
||||
} else {
|
||||
rp->process_discovered_references(soft_ref_policy,
|
||||
&_is_alive_closure,
|
||||
rp->process_discovered_references(&_is_alive_closure,
|
||||
&cmsKeepAliveClosure,
|
||||
&cmsDrainMarkingStackClosure,
|
||||
NULL);
|
||||
@ -6163,8 +6155,8 @@ void CMSCollector::verify_ok_to_terminate() const {
|
||||
#endif
|
||||
|
||||
size_t CMSCollector::block_size_using_printezis_bits(HeapWord* addr) const {
|
||||
assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
|
||||
"missing Printezis mark?");
|
||||
assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
|
||||
"missing Printezis mark?");
|
||||
HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
|
||||
size_t size = pointer_delta(nextOneAddr + 1, addr);
|
||||
assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
|
||||
@ -8302,8 +8294,29 @@ void CMSKeepAliveClosure::do_oop(oop obj) {
|
||||
}
|
||||
)
|
||||
if (simulate_overflow || !_mark_stack->push(obj)) {
|
||||
_collector->push_on_overflow_list(obj);
|
||||
_collector->_ser_kac_ovflw++;
|
||||
if (_concurrent_precleaning) {
|
||||
// We dirty the overflown object and let the remark
|
||||
// phase deal with it.
|
||||
assert(_collector->overflow_list_is_empty(), "Error");
|
||||
// In the case of object arrays, we need to dirty all of
|
||||
// the cards that the object spans. No locking or atomics
|
||||
// are needed since no one else can be mutating the mod union
|
||||
// table.
|
||||
if (obj->is_objArray()) {
|
||||
size_t sz = obj->size();
|
||||
HeapWord* end_card_addr =
|
||||
(HeapWord*)round_to((intptr_t)(addr+sz), CardTableModRefBS::card_size);
|
||||
MemRegion redirty_range = MemRegion(addr, end_card_addr);
|
||||
assert(!redirty_range.is_empty(), "Arithmetical tautology");
|
||||
_collector->_modUnionTable.mark_range(redirty_range);
|
||||
} else {
|
||||
_collector->_modUnionTable.mark(addr);
|
||||
}
|
||||
_collector->_ser_kac_preclean_ovflw++;
|
||||
} else {
|
||||
_collector->push_on_overflow_list(obj);
|
||||
_collector->_ser_kac_ovflw++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8400,6 +8413,8 @@ const char* CMSExpansionCause::to_string(CMSExpansionCause::Cause cause) {
|
||||
void CMSDrainMarkingStackClosure::do_void() {
|
||||
// the max number to take from overflow list at a time
|
||||
const size_t num = _mark_stack->capacity()/4;
|
||||
assert(!_concurrent_precleaning || _collector->overflow_list_is_empty(),
|
||||
"Overflow list should be NULL during concurrent phases");
|
||||
while (!_mark_stack->isEmpty() ||
|
||||
// if stack is empty, check the overflow list
|
||||
_collector->take_from_overflow_list(num, _mark_stack)) {
|
||||
|
@ -592,6 +592,7 @@ class CMSCollector: public CHeapObj {
|
||||
size_t _ser_pmc_preclean_ovflw;
|
||||
size_t _ser_pmc_remark_ovflw;
|
||||
size_t _par_pmc_remark_ovflw;
|
||||
size_t _ser_kac_preclean_ovflw;
|
||||
size_t _ser_kac_ovflw;
|
||||
size_t _par_kac_ovflw;
|
||||
NOT_PRODUCT(size_t _num_par_pushes;)
|
||||
@ -1749,21 +1750,30 @@ class SweepClosure: public BlkClosureCareful {
|
||||
// work-routine/closure used to complete transitive
|
||||
// marking of objects as live after a certain point
|
||||
// in which an initial set has been completely accumulated.
|
||||
// This closure is currently used both during the final
|
||||
// remark stop-world phase, as well as during the concurrent
|
||||
// precleaning of the discovered reference lists.
|
||||
class CMSDrainMarkingStackClosure: public VoidClosure {
|
||||
CMSCollector* _collector;
|
||||
MemRegion _span;
|
||||
CMSMarkStack* _mark_stack;
|
||||
CMSBitMap* _bit_map;
|
||||
CMSKeepAliveClosure* _keep_alive;
|
||||
bool _concurrent_precleaning;
|
||||
public:
|
||||
CMSDrainMarkingStackClosure(CMSCollector* collector, MemRegion span,
|
||||
CMSBitMap* bit_map, CMSMarkStack* mark_stack,
|
||||
CMSKeepAliveClosure* keep_alive):
|
||||
CMSKeepAliveClosure* keep_alive,
|
||||
bool cpc):
|
||||
_collector(collector),
|
||||
_span(span),
|
||||
_bit_map(bit_map),
|
||||
_mark_stack(mark_stack),
|
||||
_keep_alive(keep_alive) { }
|
||||
_keep_alive(keep_alive),
|
||||
_concurrent_precleaning(cpc) {
|
||||
assert(_concurrent_precleaning == _keep_alive->concurrent_precleaning(),
|
||||
"Mismatch");
|
||||
}
|
||||
|
||||
void do_void();
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -811,6 +811,7 @@ void ConcurrentMark::checkpointRootsInitialPost() {
|
||||
ReferenceProcessor* rp = g1h->ref_processor();
|
||||
rp->verify_no_references_recorded();
|
||||
rp->enable_discovery(); // enable ("weak") refs discovery
|
||||
rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle
|
||||
|
||||
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
|
||||
satb_mq_set.set_process_completed_threshold(G1SATBProcessCompletedThreshold);
|
||||
@ -1829,32 +1830,21 @@ class G1CMDrainMarkingStackClosure: public VoidClosure {
|
||||
void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
ReferencePolicy* soft_ref_policy;
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
ReferenceProcessor* rp = g1h->ref_processor();
|
||||
|
||||
// Process weak references.
|
||||
if (clear_all_soft_refs) {
|
||||
soft_ref_policy = new AlwaysClearPolicy();
|
||||
} else {
|
||||
#ifdef COMPILER2
|
||||
soft_ref_policy = new LRUMaxHeapPolicy();
|
||||
#else
|
||||
soft_ref_policy = new LRUCurrentHeapPolicy();
|
||||
#endif
|
||||
}
|
||||
rp->setup_policy(clear_all_soft_refs);
|
||||
assert(_markStack.isEmpty(), "mark stack should be empty");
|
||||
|
||||
G1CollectedHeap* g1 = G1CollectedHeap::heap();
|
||||
G1CMIsAliveClosure g1IsAliveClosure(g1);
|
||||
|
||||
G1CMKeepAliveClosure g1KeepAliveClosure(g1, this, nextMarkBitMap());
|
||||
G1CMIsAliveClosure g1IsAliveClosure (g1h);
|
||||
G1CMKeepAliveClosure g1KeepAliveClosure(g1h, this, nextMarkBitMap());
|
||||
G1CMDrainMarkingStackClosure
|
||||
g1DrainMarkingStackClosure(nextMarkBitMap(), &_markStack,
|
||||
&g1KeepAliveClosure);
|
||||
|
||||
// XXXYYY Also: copy the parallel ref processing code from CMS.
|
||||
ReferenceProcessor* rp = g1->ref_processor();
|
||||
rp->process_discovered_references(soft_ref_policy,
|
||||
&g1IsAliveClosure,
|
||||
rp->process_discovered_references(&g1IsAliveClosure,
|
||||
&g1KeepAliveClosure,
|
||||
&g1DrainMarkingStackClosure,
|
||||
NULL);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -891,6 +891,7 @@ void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs,
|
||||
ReferenceProcessorIsAliveMutator rp_is_alive_null(ref_processor(), NULL);
|
||||
|
||||
ref_processor()->enable_discovery();
|
||||
ref_processor()->setup_policy(clear_all_soft_refs);
|
||||
|
||||
// Do collection work
|
||||
{
|
||||
@ -2463,7 +2464,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(HeapRegion* popular_region) {
|
||||
|
||||
COMPILER2_PRESENT(DerivedPointerTable::clear());
|
||||
|
||||
// We want to turn off ref discovere, if necessary, and turn it back on
|
||||
// We want to turn off ref discovery, if necessary, and turn it back on
|
||||
// on again later if we do.
|
||||
bool was_enabled = ref_processor()->discovery_enabled();
|
||||
if (was_enabled) ref_processor()->disable_discovery();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -33,8 +33,9 @@ void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
|
||||
|
||||
// hook up weak ref data so it can be used during Mark-Sweep
|
||||
assert(GenMarkSweep::ref_processor() == NULL, "no stomping");
|
||||
GenMarkSweep::_ref_processor = rp;
|
||||
assert(rp != NULL, "should be non-NULL");
|
||||
GenMarkSweep::_ref_processor = rp;
|
||||
rp->setup_policy(clear_all_softrefs);
|
||||
|
||||
// When collecting the permanent generation methodOops may be moving,
|
||||
// so we either have to flush all bcp data or convert it into bci.
|
||||
@ -121,23 +122,12 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
|
||||
&GenMarkSweep::follow_root_closure);
|
||||
|
||||
// Process reference objects found during marking
|
||||
ReferencePolicy *soft_ref_policy;
|
||||
if (clear_all_softrefs) {
|
||||
soft_ref_policy = new AlwaysClearPolicy();
|
||||
} else {
|
||||
#ifdef COMPILER2
|
||||
soft_ref_policy = new LRUMaxHeapPolicy();
|
||||
#else
|
||||
soft_ref_policy = new LRUCurrentHeapPolicy();
|
||||
#endif
|
||||
}
|
||||
assert(soft_ref_policy != NULL,"No soft reference policy");
|
||||
GenMarkSweep::ref_processor()->process_discovered_references(
|
||||
soft_ref_policy,
|
||||
&GenMarkSweep::is_alive,
|
||||
&GenMarkSweep::keep_alive,
|
||||
&GenMarkSweep::follow_stack_closure,
|
||||
NULL);
|
||||
ReferenceProcessor* rp = GenMarkSweep::ref_processor();
|
||||
rp->setup_policy(clear_all_softrefs);
|
||||
rp->process_discovered_references(&GenMarkSweep::is_alive,
|
||||
&GenMarkSweep::keep_alive,
|
||||
&GenMarkSweep::follow_stack_closure,
|
||||
NULL);
|
||||
|
||||
// Follow system dictionary roots and unload classes
|
||||
bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
// Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
//
|
||||
// This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -759,17 +759,12 @@ void ParNewGeneration::collect(bool full,
|
||||
thread_state_set.steals(),
|
||||
thread_state_set.pops()+thread_state_set.steals());
|
||||
}
|
||||
assert(thread_state_set.pushes() == thread_state_set.pops() + thread_state_set.steals(),
|
||||
assert(thread_state_set.pushes() == thread_state_set.pops()
|
||||
+ thread_state_set.steals(),
|
||||
"Or else the queues are leaky.");
|
||||
|
||||
// For now, process discovered weak refs sequentially.
|
||||
#ifdef COMPILER2
|
||||
ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy();
|
||||
#else
|
||||
ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy();
|
||||
#endif // COMPILER2
|
||||
|
||||
// Process (weak) reference objects found during scavenge.
|
||||
ReferenceProcessor* rp = ref_processor();
|
||||
IsAliveClosure is_alive(this);
|
||||
ScanWeakRefClosure scan_weak_ref(this);
|
||||
KeepAliveClosure keep_alive(&scan_weak_ref);
|
||||
@ -778,18 +773,17 @@ void ParNewGeneration::collect(bool full,
|
||||
set_promo_failure_scan_stack_closure(&scan_without_gc_barrier);
|
||||
EvacuateFollowersClosureGeneral evacuate_followers(gch, _level,
|
||||
&scan_without_gc_barrier, &scan_with_gc_barrier);
|
||||
if (ref_processor()->processing_is_mt()) {
|
||||
rp->setup_policy(clear_all_soft_refs);
|
||||
if (rp->processing_is_mt()) {
|
||||
ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
|
||||
ref_processor()->process_discovered_references(
|
||||
soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers,
|
||||
&task_executor);
|
||||
rp->process_discovered_references(&is_alive, &keep_alive,
|
||||
&evacuate_followers, &task_executor);
|
||||
} else {
|
||||
thread_state_set.flush();
|
||||
gch->set_par_threads(0); // 0 ==> non-parallel.
|
||||
gch->save_marks();
|
||||
ref_processor()->process_discovered_references(
|
||||
soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers,
|
||||
NULL);
|
||||
rp->process_discovered_references(&is_alive, &keep_alive,
|
||||
&evacuate_followers, NULL);
|
||||
}
|
||||
if (!promotion_failed()) {
|
||||
// Swap the survivor spaces.
|
||||
@ -851,14 +845,14 @@ void ParNewGeneration::collect(bool full,
|
||||
|
||||
SpecializationStats::print();
|
||||
|
||||
ref_processor()->set_enqueuing_is_done(true);
|
||||
if (ref_processor()->processing_is_mt()) {
|
||||
rp->set_enqueuing_is_done(true);
|
||||
if (rp->processing_is_mt()) {
|
||||
ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
|
||||
ref_processor()->enqueue_discovered_references(&task_executor);
|
||||
rp->enqueue_discovered_references(&task_executor);
|
||||
} else {
|
||||
ref_processor()->enqueue_discovered_references(NULL);
|
||||
rp->enqueue_discovered_references(NULL);
|
||||
}
|
||||
ref_processor()->verify_no_references_recorded();
|
||||
rp->verify_no_references_recorded();
|
||||
}
|
||||
|
||||
static int sum;
|
||||
@ -1211,7 +1205,7 @@ ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) {
|
||||
int n = 0;
|
||||
while (cur != NULL) {
|
||||
oop obj_to_push = cur->forwardee();
|
||||
oop next = oop(cur->klass());
|
||||
oop next = oop(cur->klass_or_null());
|
||||
cur->set_klass(obj_to_push->klass());
|
||||
if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) {
|
||||
obj_to_push = cur;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -172,6 +172,7 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
||||
COMPILER2_PRESENT(DerivedPointerTable::clear());
|
||||
|
||||
ref_processor()->enable_discovery();
|
||||
ref_processor()->setup_policy(clear_all_softrefs);
|
||||
|
||||
mark_sweep_phase1(clear_all_softrefs);
|
||||
|
||||
@ -517,20 +518,9 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
||||
|
||||
// Process reference objects found during marking
|
||||
{
|
||||
ReferencePolicy *soft_ref_policy;
|
||||
if (clear_all_softrefs) {
|
||||
soft_ref_policy = new AlwaysClearPolicy();
|
||||
} else {
|
||||
#ifdef COMPILER2
|
||||
soft_ref_policy = new LRUMaxHeapPolicy();
|
||||
#else
|
||||
soft_ref_policy = new LRUCurrentHeapPolicy();
|
||||
#endif // COMPILER2
|
||||
}
|
||||
assert(soft_ref_policy != NULL,"No soft reference policy");
|
||||
ref_processor()->setup_policy(clear_all_softrefs);
|
||||
ref_processor()->process_discovered_references(
|
||||
soft_ref_policy, is_alive_closure(), mark_and_push_closure(),
|
||||
follow_stack_closure(), NULL);
|
||||
is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL);
|
||||
}
|
||||
|
||||
// Follow system dictionary roots and unload classes
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1578,6 +1578,7 @@ void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
|
||||
COMPILER2_PRESENT(DerivedPointerTable::clear());
|
||||
|
||||
ref_processor()->enable_discovery();
|
||||
ref_processor()->setup_policy(maximum_heap_compaction);
|
||||
|
||||
bool marked_for_unloading = false;
|
||||
|
||||
@ -1894,26 +1895,14 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
|
||||
// Process reference objects found during marking
|
||||
{
|
||||
TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty);
|
||||
ReferencePolicy *soft_ref_policy;
|
||||
if (maximum_heap_compaction) {
|
||||
soft_ref_policy = new AlwaysClearPolicy();
|
||||
} else {
|
||||
#ifdef COMPILER2
|
||||
soft_ref_policy = new LRUMaxHeapPolicy();
|
||||
#else
|
||||
soft_ref_policy = new LRUCurrentHeapPolicy();
|
||||
#endif // COMPILER2
|
||||
}
|
||||
assert(soft_ref_policy != NULL, "No soft reference policy");
|
||||
if (ref_processor()->processing_is_mt()) {
|
||||
RefProcTaskExecutor task_executor;
|
||||
ref_processor()->process_discovered_references(
|
||||
soft_ref_policy, is_alive_closure(), &mark_and_push_closure,
|
||||
&follow_stack_closure, &task_executor);
|
||||
is_alive_closure(), &mark_and_push_closure, &follow_stack_closure,
|
||||
&task_executor);
|
||||
} else {
|
||||
ref_processor()->process_discovered_references(
|
||||
soft_ref_policy, is_alive_closure(), &mark_and_push_closure,
|
||||
&follow_stack_closure, NULL);
|
||||
is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -330,6 +330,7 @@ bool PSScavenge::invoke_no_policy() {
|
||||
COMPILER2_PRESENT(DerivedPointerTable::clear());
|
||||
|
||||
reference_processor()->enable_discovery();
|
||||
reference_processor()->setup_policy(false);
|
||||
|
||||
// We track how much was promoted to the next generation for
|
||||
// the AdaptiveSizePolicy.
|
||||
@ -394,24 +395,16 @@ bool PSScavenge::invoke_no_policy() {
|
||||
|
||||
// Process reference objects discovered during scavenge
|
||||
{
|
||||
#ifdef COMPILER2
|
||||
ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy();
|
||||
#else
|
||||
ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy();
|
||||
#endif // COMPILER2
|
||||
|
||||
reference_processor()->setup_policy(false); // not always_clear
|
||||
PSKeepAliveClosure keep_alive(promotion_manager);
|
||||
PSEvacuateFollowersClosure evac_followers(promotion_manager);
|
||||
assert(soft_ref_policy != NULL,"No soft reference policy");
|
||||
if (reference_processor()->processing_is_mt()) {
|
||||
PSRefProcTaskExecutor task_executor;
|
||||
reference_processor()->process_discovered_references(
|
||||
soft_ref_policy, &_is_alive_closure, &keep_alive, &evac_followers,
|
||||
&task_executor);
|
||||
&_is_alive_closure, &keep_alive, &evac_followers, &task_executor);
|
||||
} else {
|
||||
reference_processor()->process_discovered_references(
|
||||
soft_ref_policy, &_is_alive_closure, &keep_alive, &evac_followers,
|
||||
NULL);
|
||||
&_is_alive_closure, &keep_alive, &evac_followers, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,9 +414,20 @@ size_t MutableNUMASpace::adaptive_chunk_size(int i, size_t limit) {
|
||||
if (limit > 0) {
|
||||
limit = round_down(limit, page_size());
|
||||
if (chunk_size > current_chunk_size(i)) {
|
||||
chunk_size = MIN2((off_t)chunk_size, (off_t)current_chunk_size(i) + (off_t)limit);
|
||||
size_t upper_bound = pages_available * page_size();
|
||||
if (upper_bound > limit &&
|
||||
current_chunk_size(i) < upper_bound - limit) {
|
||||
// The resulting upper bound should not exceed the available
|
||||
// amount of memory (pages_available * page_size()).
|
||||
upper_bound = current_chunk_size(i) + limit;
|
||||
}
|
||||
chunk_size = MIN2(chunk_size, upper_bound);
|
||||
} else {
|
||||
chunk_size = MAX2((off_t)chunk_size, (off_t)current_chunk_size(i) - (off_t)limit);
|
||||
size_t lower_bound = page_size();
|
||||
if (current_chunk_size(i) > limit) { // lower_bound shouldn't underflow.
|
||||
lower_bound = current_chunk_size(i) - limit;
|
||||
}
|
||||
chunk_size = MAX2(chunk_size, lower_bound);
|
||||
}
|
||||
}
|
||||
assert(chunk_size <= pages_available * page_size(), "Chunk size out of range");
|
||||
|
@ -2303,6 +2303,7 @@ javaCalls.cpp handles.inline.hpp
|
||||
javaCalls.cpp interfaceSupport.hpp
|
||||
javaCalls.cpp interpreter.hpp
|
||||
javaCalls.cpp javaCalls.hpp
|
||||
javaCalls.cpp jniCheck.hpp
|
||||
javaCalls.cpp linkResolver.hpp
|
||||
javaCalls.cpp mutexLocker.hpp
|
||||
javaCalls.cpp nmethod.hpp
|
||||
@ -3434,6 +3435,7 @@ referenceProcessor.cpp referenceProcessor.hpp
|
||||
referenceProcessor.cpp systemDictionary.hpp
|
||||
|
||||
referenceProcessor.hpp instanceRefKlass.hpp
|
||||
referenceProcessor.hpp referencePolicy.hpp
|
||||
|
||||
reflection.cpp arguments.hpp
|
||||
reflection.cpp handles.inline.hpp
|
||||
|
@ -115,6 +115,8 @@ heapInspection.cpp klassOop.hpp
|
||||
heapInspection.cpp os.hpp
|
||||
heapInspection.cpp resourceArea.hpp
|
||||
|
||||
javaCalls.cpp jniCheck.hpp
|
||||
|
||||
jniCheck.cpp fieldDescriptor.hpp
|
||||
jniCheck.cpp handles.hpp
|
||||
jniCheck.cpp instanceKlass.hpp
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -540,14 +540,6 @@ void DefNewGeneration::collect(bool full,
|
||||
assert(gch->no_allocs_since_save_marks(0),
|
||||
"save marks have not been newly set.");
|
||||
|
||||
// Weak refs.
|
||||
// FIXME: Are these storage leaks, or are they resource objects?
|
||||
#ifdef COMPILER2
|
||||
ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy();
|
||||
#else
|
||||
ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy();
|
||||
#endif // COMPILER2
|
||||
|
||||
// Not very pretty.
|
||||
CollectorPolicy* cp = gch->collector_policy();
|
||||
|
||||
@ -574,8 +566,10 @@ void DefNewGeneration::collect(bool full,
|
||||
evacuate_followers.do_void();
|
||||
|
||||
FastKeepAliveClosure keep_alive(this, &scan_weak_ref);
|
||||
ref_processor()->process_discovered_references(
|
||||
soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers, NULL);
|
||||
ReferenceProcessor* rp = ref_processor();
|
||||
rp->setup_policy(clear_all_soft_refs);
|
||||
rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers,
|
||||
NULL);
|
||||
if (!promotion_failed()) {
|
||||
// Swap the survivor spaces.
|
||||
eden()->clear(SpaceDecorator::Mangle);
|
||||
|
@ -525,8 +525,9 @@ void GenCollectedHeap::do_collection(bool full,
|
||||
if (rp->discovery_is_atomic()) {
|
||||
rp->verify_no_references_recorded();
|
||||
rp->enable_discovery();
|
||||
rp->setup_policy(clear_all_soft_refs);
|
||||
} else {
|
||||
// collect() will enable discovery as appropriate
|
||||
// collect() below will enable discovery as appropriate
|
||||
}
|
||||
_gens[i]->collect(full, clear_all_soft_refs, size, is_tlab);
|
||||
if (!rp->enqueuing_is_done()) {
|
||||
|
@ -31,8 +31,9 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp,
|
||||
|
||||
// hook up weak ref data so it can be used during Mark-Sweep
|
||||
assert(ref_processor() == NULL, "no stomping");
|
||||
_ref_processor = rp;
|
||||
assert(rp != NULL, "should be non-NULL");
|
||||
_ref_processor = rp;
|
||||
rp->setup_policy(clear_all_softrefs);
|
||||
|
||||
TraceTime t1("Full GC", PrintGC && !PrintGCDetails, true, gclog_or_tty);
|
||||
|
||||
@ -245,20 +246,9 @@ void GenMarkSweep::mark_sweep_phase1(int level,
|
||||
|
||||
// Process reference objects found during marking
|
||||
{
|
||||
ReferencePolicy *soft_ref_policy;
|
||||
if (clear_all_softrefs) {
|
||||
soft_ref_policy = new AlwaysClearPolicy();
|
||||
} else {
|
||||
#ifdef COMPILER2
|
||||
soft_ref_policy = new LRUMaxHeapPolicy();
|
||||
#else
|
||||
soft_ref_policy = new LRUCurrentHeapPolicy();
|
||||
#endif // COMPILER2
|
||||
}
|
||||
assert(soft_ref_policy != NULL,"No soft reference policy");
|
||||
ref_processor()->setup_policy(clear_all_softrefs);
|
||||
ref_processor()->process_discovered_references(
|
||||
soft_ref_policy, &is_alive, &keep_alive,
|
||||
&follow_stack_closure, NULL);
|
||||
&is_alive, &keep_alive, &follow_stack_closure, NULL);
|
||||
}
|
||||
|
||||
// Follow system dictionary roots and unload classes
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,6 +26,11 @@
|
||||
# include "incls/_referencePolicy.cpp.incl"
|
||||
|
||||
LRUCurrentHeapPolicy::LRUCurrentHeapPolicy() {
|
||||
setup();
|
||||
}
|
||||
|
||||
// Capture state (of-the-VM) information needed to evaluate the policy
|
||||
void LRUCurrentHeapPolicy::setup() {
|
||||
_max_interval = (Universe::get_heap_free_at_last_gc() / M) * SoftRefLRUPolicyMSPerMB;
|
||||
assert(_max_interval >= 0,"Sanity check");
|
||||
}
|
||||
@ -47,6 +52,11 @@ bool LRUCurrentHeapPolicy::should_clear_reference(oop p) {
|
||||
/////////////////////// MaxHeap //////////////////////
|
||||
|
||||
LRUMaxHeapPolicy::LRUMaxHeapPolicy() {
|
||||
setup();
|
||||
}
|
||||
|
||||
// Capture state (of-the-VM) information needed to evaluate the policy
|
||||
void LRUMaxHeapPolicy::setup() {
|
||||
size_t max_heap = MaxHeapSize;
|
||||
max_heap -= Universe::get_heap_used_at_last_gc();
|
||||
max_heap /= M;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,9 +26,11 @@
|
||||
// should be cleared.
|
||||
|
||||
|
||||
class ReferencePolicy : public ResourceObj {
|
||||
class ReferencePolicy : public CHeapObj {
|
||||
public:
|
||||
virtual bool should_clear_reference(oop p) { ShouldNotReachHere(); return true; }
|
||||
// Capture state (of-the-VM) information needed to evaluate the policy
|
||||
virtual void setup() { /* do nothing */ }
|
||||
};
|
||||
|
||||
class NeverClearPolicy : public ReferencePolicy {
|
||||
@ -48,6 +50,8 @@ class LRUCurrentHeapPolicy : public ReferencePolicy {
|
||||
public:
|
||||
LRUCurrentHeapPolicy();
|
||||
|
||||
// Capture state (of-the-VM) information needed to evaluate the policy
|
||||
void setup();
|
||||
bool should_clear_reference(oop p);
|
||||
};
|
||||
|
||||
@ -58,5 +62,7 @@ class LRUMaxHeapPolicy : public ReferencePolicy {
|
||||
public:
|
||||
LRUMaxHeapPolicy();
|
||||
|
||||
// Capture state (of-the-VM) information needed to evaluate the policy
|
||||
void setup();
|
||||
bool should_clear_reference(oop p);
|
||||
};
|
||||
|
@ -25,6 +25,11 @@
|
||||
# include "incls/_precompiled.incl"
|
||||
# include "incls/_referenceProcessor.cpp.incl"
|
||||
|
||||
ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
|
||||
ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL;
|
||||
oop ReferenceProcessor::_sentinelRef = NULL;
|
||||
const int subclasses_of_ref = REF_PHANTOM - REF_OTHER;
|
||||
|
||||
// List of discovered references.
|
||||
class DiscoveredList {
|
||||
public:
|
||||
@ -47,7 +52,9 @@ public:
|
||||
}
|
||||
bool empty() const { return head() == ReferenceProcessor::sentinel_ref(); }
|
||||
size_t length() { return _len; }
|
||||
void set_length(size_t len) { _len = len; }
|
||||
void set_length(size_t len) { _len = len; }
|
||||
void inc_length(size_t inc) { _len += inc; assert(_len > 0, "Error"); }
|
||||
void dec_length(size_t dec) { _len -= dec; }
|
||||
private:
|
||||
// Set value depending on UseCompressedOops. This could be a template class
|
||||
// but then we have to fix all the instantiations and declarations that use this class.
|
||||
@ -56,10 +63,6 @@ private:
|
||||
size_t _len;
|
||||
};
|
||||
|
||||
oop ReferenceProcessor::_sentinelRef = NULL;
|
||||
|
||||
const int subclasses_of_ref = REF_PHANTOM - REF_OTHER;
|
||||
|
||||
void referenceProcessor_init() {
|
||||
ReferenceProcessor::init_statics();
|
||||
}
|
||||
@ -80,6 +83,12 @@ void ReferenceProcessor::init_statics() {
|
||||
}
|
||||
assert(_sentinelRef != NULL && _sentinelRef->is_oop(),
|
||||
"Just constructed it!");
|
||||
_always_clear_soft_ref_policy = new AlwaysClearPolicy();
|
||||
_default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
|
||||
NOT_COMPILER2(LRUCurrentHeapPolicy());
|
||||
if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
|
||||
vm_exit_during_initialization("Could not allocate reference policy object");
|
||||
}
|
||||
guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
|
||||
RefDiscoveryPolicy == ReferentBasedDiscovery,
|
||||
"Unrecongnized RefDiscoveryPolicy");
|
||||
@ -106,6 +115,7 @@ ReferenceProcessor::create_ref_processor(MemRegion span,
|
||||
vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
|
||||
}
|
||||
rp->set_is_alive_non_header(is_alive_non_header);
|
||||
rp->setup_policy(false /* default soft ref policy */);
|
||||
return rp;
|
||||
}
|
||||
|
||||
@ -192,7 +202,6 @@ void ReferenceProcessor::update_soft_ref_master_clock() {
|
||||
}
|
||||
|
||||
void ReferenceProcessor::process_discovered_references(
|
||||
ReferencePolicy* policy,
|
||||
BoolObjectClosure* is_alive,
|
||||
OopClosure* keep_alive,
|
||||
VoidClosure* complete_gc,
|
||||
@ -207,7 +216,7 @@ void ReferenceProcessor::process_discovered_references(
|
||||
// Soft references
|
||||
{
|
||||
TraceTime tt("SoftReference", trace_time, false, gclog_or_tty);
|
||||
process_discovered_reflist(_discoveredSoftRefs, policy, true,
|
||||
process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
|
||||
is_alive, keep_alive, complete_gc, task_executor);
|
||||
}
|
||||
|
||||
@ -436,13 +445,13 @@ public:
|
||||
// The "allow_null_referent" argument tells us to allow for the possibility
|
||||
// of a NULL referent in the discovered Reference object. This typically
|
||||
// happens in the case of concurrent collectors that may have done the
|
||||
// discovery concurrently or interleaved with mutator execution.
|
||||
// discovery concurrently, or interleaved, with mutator execution.
|
||||
inline void load_ptrs(DEBUG_ONLY(bool allow_null_referent));
|
||||
|
||||
// Move to the next discovered reference.
|
||||
inline void next();
|
||||
|
||||
// Remove the current reference from the list and move to the next.
|
||||
// Remove the current reference from the list
|
||||
inline void remove();
|
||||
|
||||
// Make the Reference object active again.
|
||||
@ -476,7 +485,6 @@ public:
|
||||
inline size_t removed() const { return _removed; }
|
||||
)
|
||||
|
||||
private:
|
||||
inline void move_to_next();
|
||||
|
||||
private:
|
||||
@ -553,7 +561,7 @@ inline void DiscoveredListIterator::remove() {
|
||||
oopDesc::store_heap_oop((oop*)_prev_next, _next);
|
||||
}
|
||||
NOT_PRODUCT(_removed++);
|
||||
move_to_next();
|
||||
_refs_list.dec_length(1);
|
||||
}
|
||||
|
||||
inline void DiscoveredListIterator::move_to_next() {
|
||||
@ -591,12 +599,13 @@ ReferenceProcessor::process_phase1(DiscoveredList& refs_list,
|
||||
gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy",
|
||||
iter.obj(), iter.obj()->blueprint()->internal_name());
|
||||
}
|
||||
// Remove Reference object from list
|
||||
iter.remove();
|
||||
// Make the Reference object active again
|
||||
iter.make_active();
|
||||
// keep the referent around
|
||||
iter.make_referent_alive();
|
||||
// Remove Reference object from list
|
||||
iter.remove();
|
||||
iter.move_to_next();
|
||||
} else {
|
||||
iter.next();
|
||||
}
|
||||
@ -629,12 +638,13 @@ ReferenceProcessor::pp2_work(DiscoveredList& refs_list,
|
||||
iter.obj(), iter.obj()->blueprint()->internal_name());
|
||||
}
|
||||
// The referent is reachable after all.
|
||||
// Remove Reference object from list.
|
||||
iter.remove();
|
||||
// Update the referent pointer as necessary: Note that this
|
||||
// should not entail any recursive marking because the
|
||||
// referent must already have been traversed.
|
||||
iter.make_referent_alive();
|
||||
// Remove Reference object from list
|
||||
iter.remove();
|
||||
iter.move_to_next();
|
||||
} else {
|
||||
iter.next();
|
||||
}
|
||||
@ -670,6 +680,7 @@ ReferenceProcessor::pp2_work_concurrent_discovery(DiscoveredList& refs_list,
|
||||
} else {
|
||||
keep_alive->do_oop((oop*)next_addr);
|
||||
}
|
||||
iter.move_to_next();
|
||||
} else {
|
||||
iter.next();
|
||||
}
|
||||
@ -832,9 +843,9 @@ void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[])
|
||||
}
|
||||
java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
|
||||
ref_lists[to_idx].set_head(move_head);
|
||||
ref_lists[to_idx].set_length(ref_lists[to_idx].length() + refs_to_move);
|
||||
ref_lists[to_idx].inc_length(refs_to_move);
|
||||
ref_lists[from_idx].set_head(new_head);
|
||||
ref_lists[from_idx].set_length(ref_lists[from_idx].length() - refs_to_move);
|
||||
ref_lists[from_idx].dec_length(refs_to_move);
|
||||
} else {
|
||||
++to_idx;
|
||||
}
|
||||
@ -923,7 +934,6 @@ void ReferenceProcessor::clean_up_discovered_references() {
|
||||
void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) {
|
||||
assert(!discovery_is_atomic(), "Else why call this method?");
|
||||
DiscoveredListIterator iter(refs_list, NULL, NULL);
|
||||
size_t length = refs_list.length();
|
||||
while (iter.has_next()) {
|
||||
iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
|
||||
oop next = java_lang_ref_Reference::next(iter.obj());
|
||||
@ -941,12 +951,11 @@ void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list)
|
||||
)
|
||||
// Remove Reference object from list
|
||||
iter.remove();
|
||||
--length;
|
||||
iter.move_to_next();
|
||||
} else {
|
||||
iter.next();
|
||||
}
|
||||
}
|
||||
refs_list.set_length(length);
|
||||
NOT_PRODUCT(
|
||||
if (PrintGCDetails && TraceReferenceGC) {
|
||||
gclog_or_tty->print(
|
||||
@ -1024,7 +1033,7 @@ ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
|
||||
// We have separate lists for enqueueing so no synchronization
|
||||
// is necessary.
|
||||
refs_list.set_head(obj);
|
||||
refs_list.set_length(refs_list.length() + 1);
|
||||
refs_list.inc_length(1);
|
||||
if (_discovered_list_needs_barrier) {
|
||||
_bs->write_ref_field((void*)discovered_addr, current_head); guarantee(false, "Needs to be fixed: YSR");
|
||||
}
|
||||
@ -1090,15 +1099,28 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
|
||||
// reachable.
|
||||
if (is_alive_non_header() != NULL) {
|
||||
oop referent = java_lang_ref_Reference::referent(obj);
|
||||
// We'd like to assert the following:
|
||||
// assert(referent != NULL, "Refs with null referents already filtered");
|
||||
// However, since this code may be executed concurrently with
|
||||
// mutators, which can clear() the referent, it is not
|
||||
// guaranteed that the referent is non-NULL.
|
||||
// In the case of non-concurrent discovery, the last
|
||||
// disjunct below should hold. It may not hold in the
|
||||
// case of concurrent discovery because mutators may
|
||||
// concurrently clear() a Reference.
|
||||
assert(UseConcMarkSweepGC || UseG1GC || referent != NULL,
|
||||
"Refs with null referents already filtered");
|
||||
if (is_alive_non_header()->do_object_b(referent)) {
|
||||
return false; // referent is reachable
|
||||
}
|
||||
}
|
||||
if (rt == REF_SOFT) {
|
||||
// For soft refs we can decide now if these are not
|
||||
// current candidates for clearing, in which case we
|
||||
// can mark through them now, rather than delaying that
|
||||
// to the reference-processing phase. Since all current
|
||||
// time-stamp policies advance the soft-ref clock only
|
||||
// at a major collection cycle, this is always currently
|
||||
// accurate.
|
||||
if (!_current_soft_ref_policy->should_clear_reference(obj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
|
||||
const oop discovered = java_lang_ref_Reference::discovered(obj);
|
||||
@ -1168,7 +1190,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
|
||||
_bs->write_ref_field((oop*)discovered_addr, current_head);
|
||||
}
|
||||
list->set_head(obj);
|
||||
list->set_length(list->length() + 1);
|
||||
list->inc_length(1);
|
||||
}
|
||||
|
||||
// In the MT discovery case, it is currently possible to see
|
||||
@ -1209,45 +1231,48 @@ void ReferenceProcessor::preclean_discovered_references(
|
||||
TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
|
||||
false, gclog_or_tty);
|
||||
for (int i = 0; i < _num_q; i++) {
|
||||
if (yield->should_return()) {
|
||||
return;
|
||||
}
|
||||
preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
|
||||
keep_alive, complete_gc, yield);
|
||||
}
|
||||
}
|
||||
if (yield->should_return()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Weak references
|
||||
{
|
||||
TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
|
||||
false, gclog_or_tty);
|
||||
for (int i = 0; i < _num_q; i++) {
|
||||
if (yield->should_return()) {
|
||||
return;
|
||||
}
|
||||
preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
|
||||
keep_alive, complete_gc, yield);
|
||||
}
|
||||
}
|
||||
if (yield->should_return()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Final references
|
||||
{
|
||||
TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
|
||||
false, gclog_or_tty);
|
||||
for (int i = 0; i < _num_q; i++) {
|
||||
if (yield->should_return()) {
|
||||
return;
|
||||
}
|
||||
preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
|
||||
keep_alive, complete_gc, yield);
|
||||
}
|
||||
}
|
||||
if (yield->should_return()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Phantom references
|
||||
{
|
||||
TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
|
||||
false, gclog_or_tty);
|
||||
for (int i = 0; i < _num_q; i++) {
|
||||
if (yield->should_return()) {
|
||||
return;
|
||||
}
|
||||
preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
|
||||
keep_alive, complete_gc, yield);
|
||||
}
|
||||
@ -1256,9 +1281,12 @@ void ReferenceProcessor::preclean_discovered_references(
|
||||
|
||||
// Walk the given discovered ref list, and remove all reference objects
|
||||
// whose referents are still alive, whose referents are NULL or which
|
||||
// are not active (have a non-NULL next field). NOTE: For this to work
|
||||
// correctly, refs discovery can not be happening concurrently with this
|
||||
// step.
|
||||
// are not active (have a non-NULL next field). NOTE: When we are
|
||||
// thus precleaning the ref lists (which happens single-threaded today),
|
||||
// we do not disable refs discovery to honour the correct semantics of
|
||||
// java.lang.Reference. As a result, we need to be careful below
|
||||
// that ref removal steps interleave safely with ref discovery steps
|
||||
// (in this thread).
|
||||
void
|
||||
ReferenceProcessor::preclean_discovered_reflist(DiscoveredList& refs_list,
|
||||
BoolObjectClosure* is_alive,
|
||||
@ -1266,7 +1294,6 @@ ReferenceProcessor::preclean_discovered_reflist(DiscoveredList& refs_list,
|
||||
VoidClosure* complete_gc,
|
||||
YieldClosure* yield) {
|
||||
DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
|
||||
size_t length = refs_list.length();
|
||||
while (iter.has_next()) {
|
||||
iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
|
||||
oop obj = iter.obj();
|
||||
@ -1281,7 +1308,6 @@ ReferenceProcessor::preclean_discovered_reflist(DiscoveredList& refs_list,
|
||||
}
|
||||
// Remove Reference object from list
|
||||
iter.remove();
|
||||
--length;
|
||||
// Keep alive its cohort.
|
||||
iter.make_referent_alive();
|
||||
if (UseCompressedOops) {
|
||||
@ -1291,12 +1317,11 @@ ReferenceProcessor::preclean_discovered_reflist(DiscoveredList& refs_list,
|
||||
oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
|
||||
keep_alive->do_oop(next_addr);
|
||||
}
|
||||
iter.move_to_next();
|
||||
} else {
|
||||
iter.next();
|
||||
}
|
||||
}
|
||||
refs_list.set_length(length);
|
||||
|
||||
// Close the reachable set
|
||||
complete_gc->do_void();
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
// ReferenceProcessor class encapsulates the per-"collector" processing
|
||||
// of "weak" references for GC. The interface is useful for supporting
|
||||
// of java.lang.Reference objects for GC. The interface is useful for supporting
|
||||
// a generational abstraction, in particular when there are multiple
|
||||
// generations that are being independently collected -- possibly
|
||||
// concurrently and/or incrementally. Note, however, that the
|
||||
@ -75,6 +75,14 @@ class ReferenceProcessor : public CHeapObj {
|
||||
// all collectors but the CMS collector).
|
||||
BoolObjectClosure* _is_alive_non_header;
|
||||
|
||||
// Soft ref clearing policies
|
||||
// . the default policy
|
||||
static ReferencePolicy* _default_soft_ref_policy;
|
||||
// . the "clear all" policy
|
||||
static ReferencePolicy* _always_clear_soft_ref_policy;
|
||||
// . the current policy below is either one of the above
|
||||
ReferencePolicy* _current_soft_ref_policy;
|
||||
|
||||
// The discovered ref lists themselves
|
||||
|
||||
// The MT'ness degree of the queues below
|
||||
@ -90,6 +98,12 @@ class ReferenceProcessor : public CHeapObj {
|
||||
DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; }
|
||||
static oop sentinel_ref() { return _sentinelRef; }
|
||||
static oop* adr_sentinel_ref() { return &_sentinelRef; }
|
||||
ReferencePolicy* setup_policy(bool always_clear) {
|
||||
_current_soft_ref_policy = always_clear ?
|
||||
_always_clear_soft_ref_policy : _default_soft_ref_policy;
|
||||
_current_soft_ref_policy->setup(); // snapshot the policy threshold
|
||||
return _current_soft_ref_policy;
|
||||
}
|
||||
|
||||
public:
|
||||
// Process references with a certain reachability level.
|
||||
@ -297,8 +311,7 @@ class ReferenceProcessor : public CHeapObj {
|
||||
bool discover_reference(oop obj, ReferenceType rt);
|
||||
|
||||
// Process references found during GC (called by the garbage collector)
|
||||
void process_discovered_references(ReferencePolicy* policy,
|
||||
BoolObjectClosure* is_alive,
|
||||
void process_discovered_references(BoolObjectClosure* is_alive,
|
||||
OopClosure* keep_alive,
|
||||
VoidClosure* complete_gc,
|
||||
AbstractRefProcTaskExecutor* task_executor);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -96,7 +96,7 @@ bool Universe::_bootstrapping = false;
|
||||
bool Universe::_fully_initialized = false;
|
||||
|
||||
size_t Universe::_heap_capacity_at_last_gc;
|
||||
size_t Universe::_heap_used_at_last_gc;
|
||||
size_t Universe::_heap_used_at_last_gc = 0;
|
||||
|
||||
CollectedHeap* Universe::_collectedHeap = NULL;
|
||||
address Universe::_heap_base = NULL;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -92,7 +92,7 @@ inline void oopDesc::set_klass_to_list_ptr(oop k) {
|
||||
// This is only to be used during GC, for from-space objects, so no
|
||||
// barrier is needed.
|
||||
if (UseCompressedOops) {
|
||||
_metadata._compressed_klass = encode_heap_oop_not_null(k);
|
||||
_metadata._compressed_klass = encode_heap_oop(k); // may be null (parnew overflow handling)
|
||||
} else {
|
||||
_metadata._klass = (klassOop)k;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -395,7 +395,13 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
|
||||
OptoReg::regname(OptoReg::c_frame_pointer),
|
||||
regalloc->reg2offset(box_reg));
|
||||
}
|
||||
format_helper( regalloc, st, obj, "MON-OBJ[", i, &scobjs );
|
||||
const char* obj_msg = "MON-OBJ[";
|
||||
if (EliminateLocks) {
|
||||
while( !box->is_BoxLock() ) box = box->in(1);
|
||||
if (box->as_BoxLock()->is_eliminated())
|
||||
obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
|
||||
}
|
||||
format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
|
||||
}
|
||||
|
||||
for (i = 0; i < (uint)scobjs.length(); i++) {
|
||||
@ -908,8 +914,9 @@ void SafePointNode::push_monitor(const FastLockNode *lock) {
|
||||
add_req(lock->box_node());
|
||||
add_req(lock->obj_node());
|
||||
} else {
|
||||
add_req(NULL);
|
||||
add_req(NULL);
|
||||
Node* top = Compile::current()->top();
|
||||
add_req(top);
|
||||
add_req(top);
|
||||
}
|
||||
jvms()->set_scloff(nextmon+MonitorEdges);
|
||||
jvms()->set_endoff(req());
|
||||
@ -1382,7 +1389,7 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
//
|
||||
// If we are locking an unescaped object, the lock/unlock is unnecessary
|
||||
//
|
||||
ConnectionGraph *cgr = Compile::current()->congraph();
|
||||
ConnectionGraph *cgr = phase->C->congraph();
|
||||
PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
|
||||
if (cgr != NULL)
|
||||
es = cgr->escape_state(obj_node(), phase);
|
||||
@ -1450,6 +1457,7 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
|
||||
// Mark it eliminated to update any counters
|
||||
lock->set_eliminated();
|
||||
lock->set_coarsened();
|
||||
}
|
||||
} else if (result != NULL && ctrl->is_Region() &&
|
||||
iter->_worklist.member(ctrl)) {
|
||||
@ -1484,7 +1492,7 @@ Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
//
|
||||
// If we are unlocking an unescaped object, the lock/unlock is unnecessary.
|
||||
//
|
||||
ConnectionGraph *cgr = Compile::current()->congraph();
|
||||
ConnectionGraph *cgr = phase->C->congraph();
|
||||
PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
|
||||
if (cgr != NULL)
|
||||
es = cgr->escape_state(obj_node(), phase);
|
||||
|
@ -780,7 +780,8 @@ public:
|
||||
//------------------------------AbstractLockNode-----------------------------------
|
||||
class AbstractLockNode: public CallNode {
|
||||
private:
|
||||
bool _eliminate; // indicates this lock can be safely eliminated
|
||||
bool _eliminate; // indicates this lock can be safely eliminated
|
||||
bool _coarsened; // indicates this lock was coarsened
|
||||
#ifndef PRODUCT
|
||||
NamedCounter* _counter;
|
||||
#endif
|
||||
@ -801,6 +802,7 @@ protected:
|
||||
public:
|
||||
AbstractLockNode(const TypeFunc *tf)
|
||||
: CallNode(tf, NULL, TypeRawPtr::BOTTOM),
|
||||
_coarsened(false),
|
||||
_eliminate(false)
|
||||
{
|
||||
#ifndef PRODUCT
|
||||
@ -819,6 +821,9 @@ public:
|
||||
// mark node as eliminated and update the counter if there is one
|
||||
void set_eliminated();
|
||||
|
||||
bool is_coarsened() { return _coarsened; }
|
||||
void set_coarsened() { _coarsened = true; }
|
||||
|
||||
// locking does not modify its arguments
|
||||
virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
|
||||
|
||||
|
@ -1532,11 +1532,6 @@ void Compile::Optimize() {
|
||||
|
||||
if (failing()) return;
|
||||
|
||||
// get rid of the connection graph since it's information is not
|
||||
// updated by optimizations
|
||||
_congraph = NULL;
|
||||
|
||||
|
||||
// Loop transforms on the ideal graph. Range Check Elimination,
|
||||
// peeling, unrolling, etc.
|
||||
|
||||
|
@ -199,7 +199,8 @@ PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n, PhaseTransform
|
||||
es = ptnode_adr(idx)->escape_state();
|
||||
|
||||
// if we have already computed a value, return it
|
||||
if (es != PointsToNode::UnknownEscape)
|
||||
if (es != PointsToNode::UnknownEscape &&
|
||||
ptnode_adr(idx)->node_type() == PointsToNode::JavaObject)
|
||||
return es;
|
||||
|
||||
// PointsTo() calls n->uncast() which can return a new ideal node.
|
||||
|
@ -44,10 +44,15 @@ BoxLockNode::BoxLockNode( int slot ) : Node( Compile::current()->root() ),
|
||||
_inmask.Insert(reg);
|
||||
}
|
||||
|
||||
//-----------------------------hash--------------------------------------------
|
||||
uint BoxLockNode::hash() const {
|
||||
return Node::hash() + _slot + (_is_eliminated ? Compile::current()->fixed_slots() : 0);
|
||||
}
|
||||
|
||||
//------------------------------cmp--------------------------------------------
|
||||
uint BoxLockNode::cmp( const Node &n ) const {
|
||||
const BoxLockNode &bn = (const BoxLockNode &)n;
|
||||
return bn._slot == _slot;
|
||||
return bn._slot == _slot && bn._is_eliminated == _is_eliminated;
|
||||
}
|
||||
|
||||
OptoReg::Name BoxLockNode::stack_slot(Node* box_node) {
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
virtual const RegMask &in_RegMask(uint) const;
|
||||
virtual const RegMask &out_RegMask() const;
|
||||
virtual uint size_of() const;
|
||||
virtual uint hash() const { return Node::hash() + _slot; }
|
||||
virtual uint hash() const;
|
||||
virtual uint cmp( const Node &n ) const;
|
||||
virtual const class Type *bottom_type() const { return TypeRawPtr::BOTTOM; }
|
||||
virtual uint ideal_reg() const { return Op_RegP; }
|
||||
|
@ -59,7 +59,7 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal
|
||||
for (uint i = old_dbg_start; i < oldcall->req(); i++) {
|
||||
Node* old_in = oldcall->in(i);
|
||||
// Clone old SafePointScalarObjectNodes, adjusting their field contents.
|
||||
if (old_in->is_SafePointScalarObject()) {
|
||||
if (old_in != NULL && old_in->is_SafePointScalarObject()) {
|
||||
SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject();
|
||||
uint old_unique = C->unique();
|
||||
Node* new_in = old_sosn->clone(jvms_adj, sosn_map);
|
||||
@ -1509,21 +1509,63 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
|
||||
if (!alock->is_eliminated()) {
|
||||
return false;
|
||||
}
|
||||
// Mark the box lock as eliminated if all correspondent locks are eliminated
|
||||
// to construct correct debug info.
|
||||
BoxLockNode* box = alock->box_node()->as_BoxLock();
|
||||
if (!box->is_eliminated()) {
|
||||
bool eliminate = true;
|
||||
for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) {
|
||||
Node *lck = box->fast_out(i);
|
||||
if (lck->is_Lock() && !lck->as_AbstractLock()->is_eliminated()) {
|
||||
eliminate = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (eliminate)
|
||||
box->set_eliminated();
|
||||
}
|
||||
if (alock->is_Lock() && !alock->is_coarsened()) {
|
||||
// Create new "eliminated" BoxLock node and use it
|
||||
// in monitor debug info for the same object.
|
||||
BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
|
||||
Node* obj = alock->obj_node();
|
||||
if (!oldbox->is_eliminated()) {
|
||||
BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
|
||||
newbox->set_eliminated();
|
||||
transform_later(newbox);
|
||||
// Replace old box node with new box for all users
|
||||
// of the same object.
|
||||
for (uint i = 0; i < oldbox->outcnt();) {
|
||||
|
||||
bool next_edge = true;
|
||||
Node* u = oldbox->raw_out(i);
|
||||
if (u == alock) {
|
||||
i++;
|
||||
continue; // It will be removed below
|
||||
}
|
||||
if (u->is_Lock() &&
|
||||
u->as_Lock()->obj_node() == obj &&
|
||||
// oldbox could be referenced in debug info also
|
||||
u->as_Lock()->box_node() == oldbox) {
|
||||
assert(u->as_Lock()->is_eliminated(), "sanity");
|
||||
_igvn.hash_delete(u);
|
||||
u->set_req(TypeFunc::Parms + 1, newbox);
|
||||
next_edge = false;
|
||||
#ifdef ASSERT
|
||||
} else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) {
|
||||
assert(u->as_Unlock()->is_eliminated(), "sanity");
|
||||
#endif
|
||||
}
|
||||
// Replace old box in monitor debug info.
|
||||
if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
|
||||
SafePointNode* sfn = u->as_SafePoint();
|
||||
JVMState* youngest_jvms = sfn->jvms();
|
||||
int max_depth = youngest_jvms->depth();
|
||||
for (int depth = 1; depth <= max_depth; depth++) {
|
||||
JVMState* jvms = youngest_jvms->of_depth(depth);
|
||||
int num_mon = jvms->nof_monitors();
|
||||
// Loop over monitors
|
||||
for (int idx = 0; idx < num_mon; idx++) {
|
||||
Node* obj_node = sfn->monitor_obj(jvms, idx);
|
||||
Node* box_node = sfn->monitor_box(jvms, idx);
|
||||
if (box_node == oldbox && obj_node == obj) {
|
||||
int j = jvms->monitor_box_offset(idx);
|
||||
_igvn.hash_delete(u);
|
||||
u->set_req(j, newbox);
|
||||
next_edge = false;
|
||||
}
|
||||
} // for (int idx = 0;
|
||||
} // for (int depth = 1;
|
||||
} // if (u->is_SafePoint()
|
||||
if (next_edge) i++;
|
||||
} // for (uint i = 0; i < oldbox->outcnt();)
|
||||
} // if (!oldbox->is_eliminated())
|
||||
} // if (alock->is_Lock() && !lock->is_coarsened())
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (PrintEliminateLocks) {
|
||||
@ -1562,6 +1604,15 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
|
||||
_igvn.subsume_node(ctrlproj, fallthroughproj);
|
||||
_igvn.hash_delete(memproj);
|
||||
_igvn.subsume_node(memproj, memproj_fallthrough);
|
||||
|
||||
// Delete FastLock node also if this Lock node is unique user
|
||||
// (a loop peeling may clone a Lock node).
|
||||
Node* flock = alock->as_Lock()->fastlock_node();
|
||||
if (flock->outcnt() == 1) {
|
||||
assert(flock->unique_out() == alock, "sanity");
|
||||
_igvn.hash_delete(flock);
|
||||
_igvn.subsume_node(flock, top());
|
||||
}
|
||||
}
|
||||
|
||||
// Seach for MemBarRelease node and delete it also.
|
||||
@ -1887,8 +1938,28 @@ void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) {
|
||||
bool PhaseMacroExpand::expand_macro_nodes() {
|
||||
if (C->macro_count() == 0)
|
||||
return false;
|
||||
// attempt to eliminate allocations
|
||||
// First, attempt to eliminate locks
|
||||
bool progress = true;
|
||||
while (progress) {
|
||||
progress = false;
|
||||
for (int i = C->macro_count(); i > 0; i--) {
|
||||
Node * n = C->macro_node(i-1);
|
||||
bool success = false;
|
||||
debug_only(int old_macro_count = C->macro_count(););
|
||||
if (n->is_AbstractLock()) {
|
||||
success = eliminate_locking_node(n->as_AbstractLock());
|
||||
} else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
|
||||
_igvn.add_users_to_worklist(n);
|
||||
_igvn.hash_delete(n);
|
||||
_igvn.subsume_node(n, n->in(1));
|
||||
success = true;
|
||||
}
|
||||
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
|
||||
progress = progress || success;
|
||||
}
|
||||
}
|
||||
// Next, attempt to eliminate allocations
|
||||
progress = true;
|
||||
while (progress) {
|
||||
progress = false;
|
||||
for (int i = C->macro_count(); i > 0; i--) {
|
||||
@ -1902,17 +1973,10 @@ bool PhaseMacroExpand::expand_macro_nodes() {
|
||||
break;
|
||||
case Node::Class_Lock:
|
||||
case Node::Class_Unlock:
|
||||
success = eliminate_locking_node(n->as_AbstractLock());
|
||||
assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
|
||||
break;
|
||||
default:
|
||||
if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
|
||||
_igvn.add_users_to_worklist(n);
|
||||
_igvn.hash_delete(n);
|
||||
_igvn.subsume_node(n, n->in(1));
|
||||
success = true;
|
||||
} else {
|
||||
assert(false, "unknown node type in macro list");
|
||||
}
|
||||
assert(false, "unknown node type in macro list");
|
||||
}
|
||||
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
|
||||
progress = progress || success;
|
||||
|
@ -849,10 +849,8 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
|
||||
// Loop over monitors and insert into array
|
||||
for(idx = 0; idx < num_mon; idx++) {
|
||||
// Grab the node that defines this monitor
|
||||
Node* box_node;
|
||||
Node* obj_node;
|
||||
box_node = sfn->monitor_box(jvms, idx);
|
||||
obj_node = sfn->monitor_obj(jvms, idx);
|
||||
Node* box_node = sfn->monitor_box(jvms, idx);
|
||||
Node* obj_node = sfn->monitor_obj(jvms, idx);
|
||||
|
||||
// Create ScopeValue for object
|
||||
ScopeValue *scval = NULL;
|
||||
@ -890,6 +888,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
|
||||
|
||||
OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node);
|
||||
Location basic_lock = Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg));
|
||||
while( !box_node->is_BoxLock() ) box_node = box_node->in(1);
|
||||
monarray->append(new MonitorValue(scval, basic_lock, box_node->as_BoxLock()->is_eliminated()));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user