提交 60760a60 编写于 作者: J jcoomes

6962931: move interned strings out of the perm gen

Reviewed-by: never, coleenp, ysr, jwilhelm
上级 e1922b9a
......@@ -162,7 +162,7 @@ Handle java_lang_String::create_from_unicode(jchar* unicode, int length, TRAPS)
}
Handle java_lang_String::create_tenured_from_unicode(jchar* unicode, int length, TRAPS) {
return basic_create_from_unicode(unicode, length, true, CHECK_NH);
return basic_create_from_unicode(unicode, length, JavaObjectsInPerm, CHECK_NH);
}
oop java_lang_String::create_oop_from_unicode(jchar* unicode, int length, TRAPS) {
......
......@@ -530,7 +530,7 @@ oop StringTable::basic_add(int index, Handle string_or_null, jchar* name,
Handle string;
// try to reuse the string if possible
if (!string_or_null.is_null() && string_or_null()->is_perm()) {
if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) {
string = string_or_null;
} else {
string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL);
......@@ -662,7 +662,7 @@ void StringTable::verify() {
for ( ; p != NULL; p = p->next()) {
oop s = p->literal();
guarantee(s != NULL, "interned string is NULL");
guarantee(s->is_perm(), "interned string not in permspace");
guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
int length;
jchar* chars = java_lang_String::as_unicode_string(s, length);
......
......@@ -5930,14 +5930,18 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
}
{
TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
// Now clean up stale oops in StringTable
StringTable::unlink(&_is_alive_closure);
TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty);
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
}
}
if (should_unload_classes() || !JavaObjectsInPerm) {
TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty);
// Now clean up stale oops in StringTable
StringTable::unlink(&_is_alive_closure);
}
verify_work_stacks_empty();
// Restore any preserved marks as a result of mark stack or
// work queue overflow
......
......@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
......@@ -439,6 +440,14 @@ bool PSScavenge::invoke_no_policy() {
reference_processor()->enqueue_discovered_references(NULL);
}
if (!JavaObjectsInPerm) {
// Unlink any dead interned Strings
StringTable::unlink(&_is_alive_closure);
// Process the remaining live ones
PSScavengeRootsClosure root_closure(promotion_manager);
StringTable::oops_do(&root_closure);
}
// Finally, flush the promotion_manager's labs, and deallocate its stacks.
PSPromotionManager::post_scavenge();
......
......@@ -86,4 +86,21 @@ inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
}
}
class PSScavengeRootsClosure: public OopClosure {
private:
PSPromotionManager* _promotion_manager;
protected:
template <class T> void do_oop_work(T *p) {
if (PSScavenge::should_scavenge(p)) {
// We never card mark roots, maybe call a func without test?
PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
}
}
public:
PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
void do_oop(oop* p) { PSScavengeRootsClosure::do_oop_work(p); }
void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); }
};
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSSCAVENGE_INLINE_HPP
......@@ -30,7 +30,7 @@
#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "gc_implementation/parallelScavenge/psTasks.hpp"
#include "memory/iterator.hpp"
#include "memory/universe.hpp"
......@@ -46,24 +46,6 @@
// ScavengeRootsTask
//
// Define before use
class PSScavengeRootsClosure: public OopClosure {
private:
PSPromotionManager* _promotion_manager;
protected:
template <class T> void do_oop_work(T *p) {
if (PSScavenge::should_scavenge(p)) {
// We never card mark roots, maybe call a func without test?
PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
}
}
public:
PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
void do_oop(oop* p) { PSScavengeRootsClosure::do_oop_work(p); }
void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); }
};
void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
assert(Universe::heap()->is_gc_active(), "called outside gc");
......
......@@ -1561,6 +1561,7 @@ void GenCollectedHeap::preload_and_dump(TRAPS) {
// thread because it requires object allocation.
LinkClassesClosure lcc(Thread::current());
object_iterate(&lcc);
ensure_parsability(false); // arg is actually don't care
tty->print_cr("done. ");
// Create and dump the shared spaces.
......
......@@ -171,11 +171,13 @@ void SharedHeap::process_strong_roots(bool activate_scope,
}
if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
if (so & SO_Strings) {
StringTable::oops_do(roots);
}
// Verify if the string table contents are in the perm gen
NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
if (so & SO_Strings || (!collecting_perm_gen && !JavaObjectsInPerm)) {
StringTable::oops_do(roots);
}
if (JavaObjectsInPerm) {
// Verify the string table contents are in the perm gen
NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
}
}
if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
......
......@@ -285,10 +285,11 @@ int constantPoolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
assert(obj->is_constantPool(), "should be constant pool");
constantPoolOop cp = (constantPoolOop) obj;
if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
oop* base = (oop*)cp->base();
for (int i = 0; i < cp->length(); ++i, ++base) {
if (cp->tags() != NULL &&
(!JavaObjectsInPerm || (AnonymousClasses && cp->has_pseudo_string()))) {
for (int i = 1; i < cp->length(); ++i) {
if (cp->tag_at(i).is_string()) {
oop* base = cp->obj_at_addr_raw(i);
if (PSScavenge::should_scavenge(base)) {
pm->claim_or_forward_depth(base);
}
......@@ -460,7 +461,8 @@ void constantPoolKlass::oop_verify_on(oop obj, outputStream* st) {
if (cp->tag_at(i).is_string()) {
if (!cp->has_pseudo_string()) {
if (entry.is_oop()) {
guarantee(entry.get_oop()->is_perm(), "should be in permspace");
guarantee(!JavaObjectsInPerm || entry.get_oop()->is_perm(),
"should be in permspace");
guarantee(entry.get_oop()->is_instance(), "should be instance");
}
} else {
......
......@@ -1116,7 +1116,7 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar
Node* sourcea = basic_plus_adr(string_object, string_object, value_offset);
Node* source = make_load(no_ctrl, sourcea, source_type, T_OBJECT, string_type->add_offset(value_offset));
Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array)) );
Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)) );
jint target_length = target_array->length();
const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
......
......@@ -1573,9 +1573,9 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
return TypeInt::make(constant.as_int());
} else if (constant.basic_type() == T_ARRAY) {
if (adr->bottom_type()->is_ptr_to_narrowoop()) {
return TypeNarrowOop::make_from_constant(constant.as_object());
return TypeNarrowOop::make_from_constant(constant.as_object(), true);
} else {
return TypeOopPtr::make_from_constant(constant.as_object());
return TypeOopPtr::make_from_constant(constant.as_object(), true);
}
}
}
......
......@@ -910,7 +910,7 @@ Node* PhaseStringOpts::fetch_static_field(GraphKit& kit, ciField* field) {
ciObject* con = field->constant_value().as_object();
// Do not "join" in the previous type; it doesn't add value,
// and may yield a vacuous result if the field is of interface type.
type = TypeOopPtr::make_from_constant(con)->isa_oopptr();
type = TypeOopPtr::make_from_constant(con, true)->isa_oopptr();
assert(type != NULL, "field singleton type must be consistent");
} else {
type = TypeOopPtr::make_from_klass(field_klass->as_klass());
......
......@@ -988,8 +988,8 @@ public:
static const TypeNarrowOop *make( const TypePtr* type);
static const TypeNarrowOop* make_from_constant(ciObject* con) {
return make(TypeOopPtr::make_from_constant(con));
static const TypeNarrowOop* make_from_constant(ciObject* con, bool require_constant = false) {
return make(TypeOopPtr::make_from_constant(con, require_constant));
}
// returns the equivalent ptr type for this compressed pointer
......
......@@ -851,7 +851,7 @@ class CommandLineFlags {
diagnostic(bool, TraceNMethodInstalls, false, \
"Trace nmethod intallation") \
\
diagnostic(intx, ScavengeRootsInCode, 0, \
diagnostic(intx, ScavengeRootsInCode, 1, \
"0: do not allow scavengable oops in the code cache; " \
"1: allow scavenging from the code cache; " \
"2: emit as many constants as the compiler can see") \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册