--- a/anonk.patch Sat Aug 30 18:16:55 2008 -0700
+++ b/anonk.patch Mon Sep 01 15:49:33 2008 -0700
@@ -1,15 +1,28 @@ diff --git a/src/share/vm/ci/ciEnv.cpp b
diff --git a/src/share/vm/ci/ciEnv.cpp b/src/share/vm/ci/ciEnv.cpp
--- a/src/share/vm/ci/ciEnv.cpp
+++ b/src/share/vm/ci/ciEnv.cpp
-@@ -484,7 +484,7 @@
+@@ -484,11 +484,16 @@
} else if (tag.is_double()) {
return ciConstant((jdouble)cpool->double_at(index));
} else if (tag.is_string() || tag.is_unresolved_string()) {
- oop string = cpool->string_at(index, THREAD);
-+ oop string = cpool->pseudo_string_at(index, THREAD);
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- record_out_of_memory_failure();
+- if (HAS_PENDING_EXCEPTION) {
+- CLEAR_PENDING_EXCEPTION;
+- record_out_of_memory_failure();
+- return ciConstant();
++ oop string = NULL;
++ if (cpool->is_pseudo_string_at(index)) {
++ string = cpool->pseudo_string_at(index);
++ } else {
++ string = cpool->string_at(index, THREAD);
++ if (HAS_PENDING_EXCEPTION) {
++ CLEAR_PENDING_EXCEPTION;
++ record_out_of_memory_failure();
++ return ciConstant();
++ }
+ }
+ ciObject* constant = get_object(string);
+ assert (constant->is_instance(), "must be an instance, or not? ");
diff --git a/src/share/vm/classfile/classFileParser.cpp b/src/share/vm/classfile/classFileParser.cpp
--- a/src/share/vm/classfile/classFileParser.cpp
+++ b/src/share/vm/classfile/classFileParser.cpp
@@ -23,7 +36,7 @@ diff --git a/src/share/vm/classfile/clas
verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
+ }
+
-+ if (has_cp_patch_at(index)) {
++ if (AnonymousClasses && has_cp_patch_at(index)) {
+ Handle patch = clear_cp_patch_at(index);
+ guarantee_property(java_lang_String::is_instance(patch()),
+ "Illegal utf8 patch at %d in class file %s",
@@ -31,7 +44,7 @@ diff --git a/src/share/vm/classfile/clas
+ char* str = java_lang_String::as_utf8_string(patch());
+ // (could use java_lang_String::as_symbol instead, but might as well batch them)
+ utf8_buffer = (u1*) str;
-+ utf8_length = strlen(str);
++ utf8_length = (int) strlen(str);
}
unsigned int hash;
@@ -41,7 +54,7 @@ diff --git a/src/share/vm/classfile/clas
class_index, CHECK_(nullHandle));
- cp->unresolved_klass_at_put(index, cp->symbol_at(class_index));
+ symbolOop name = cp->symbol_at(class_index);
-+ klassOop wkk = NULL; //%%% S.B. SystemDictionary::find_well_known_klass(name);
++ klassOop wkk = SystemDictionary::find_well_known_klass(name);
+ if (wkk != NULL) {
+ cp->klass_at_put(index, wkk); // eagerly resolve
+ } else {
@@ -50,12 +63,13 @@ diff --git a/src/share/vm/classfile/clas
}
break;
case JVM_CONSTANT_UnresolvedString :
-@@ -326,16 +344,45 @@
+@@ -326,16 +344,46 @@
} // end of switch
} // end of for
+ if (_cp_patches != NULL) {
+ // need to treat this_class specially...
++ assert(AnonymousClasses, "");
+ int this_class_index;
+ {
+ cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len
@@ -96,11 +110,12 @@ diff --git a/src/share/vm/classfile/clas
verify_legal_class_name(class_name, CHECK_(nullHandle));
break;
}
-@@ -378,6 +425,71 @@
+@@ -378,6 +426,73 @@
}
+void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
++ assert(AnonymousClasses, "");
+ BasicType patch_type = T_VOID;
+ switch (cp->tag_at(index).value()) {
+
@@ -125,9 +140,10 @@ diff --git a/src/share/vm/classfile/clas
+ // Patching a string means pre-resolving it.
+ // The spelling in the constant pool is ignored.
+ // The constant reference may be any object whatever.
-+ // If it is not a real string, the constant is referred to
-+ // as a "pseudo-string".
-+ cp->string_at_put(index, patch());
++ // If it is not a real interned string, the constant is referred
++ // to as a "pseudo-string", and must be presented to the CP
++ // explicitly, because it may require scavenging.
++ cp->pseudo_string_at_put(index, patch());
+ break;
+
+ case JVM_CONSTANT_Integer : patch_type = T_INT; goto patch_prim;
@@ -168,7 +184,7 @@ diff --git a/src/share/vm/classfile/clas
class NameSigHash: public ResourceObj {
public:
symbolOop _name; // name
-@@ -448,25 +560,32 @@
+@@ -448,25 +563,32 @@
int index;
for (index = 0; index < length; index++) {
u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
@@ -216,7 +232,7 @@ diff --git a/src/share/vm/classfile/clas
if (!Klass::cast(interf())->is_interface()) {
THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
-@@ -877,8 +996,7 @@
+@@ -877,8 +999,7 @@
"Illegal exception table handler in class file %s", CHECK_(nullHandle));
if (catch_type_index != 0) {
guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
@@ -226,7 +242,7 @@ diff --git a/src/share/vm/classfile/clas
"Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
}
}
-@@ -1117,7 +1235,7 @@
+@@ -1117,7 +1238,7 @@
} else if (tag == ITEM_Object) {
u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK);
guarantee_property(valid_cp_range(class_index, cp->length()) &&
@@ -235,7 +251,7 @@ diff --git a/src/share/vm/classfile/clas
"Bad class index %u in StackMap in class file %s",
class_index, CHECK);
} else if (tag == ITEM_Uninitialized) {
-@@ -2349,6 +2467,7 @@
+@@ -2349,6 +2470,7 @@
instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
Handle class_loader,
Handle protection_domain,
@@ -243,7 +259,7 @@ diff --git a/src/share/vm/classfile/clas
symbolHandle& parsed_name,
TRAPS) {
// So that JVMTI can cache class file in the state before retransformable agents
-@@ -2380,6 +2499,7 @@
+@@ -2380,6 +2502,7 @@
}
}
@@ -251,7 +267,7 @@ diff --git a/src/share/vm/classfile/clas
instanceKlassHandle nullHandle;
-@@ -2510,14 +2630,22 @@
+@@ -2510,14 +2633,22 @@
CHECK_(nullHandle));
} else {
check_property(valid_cp_range(super_class_index, cp_size) &&
@@ -277,7 +293,7 @@ diff --git a/src/share/vm/classfile/clas
"Bad superclass name in class file %s", CHECK_(nullHandle));
}
}
-@@ -2557,7 +2685,7 @@
+@@ -2557,7 +2688,7 @@
objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
// We check super class after class file is parsed and format is checked
@@ -286,7 +302,7 @@ diff --git a/src/share/vm/classfile/clas
symbolHandle sk (THREAD, cp->klass_name_at(super_class_index));
if (access_flags.is_interface()) {
// Before attempting to resolve the superclass, check for class format
-@@ -2574,6 +2702,9 @@
+@@ -2574,6 +2705,9 @@
CHECK_(nullHandle));
KlassHandle kh (THREAD, k);
super_klass = instanceKlassHandle(THREAD, kh());
@@ -296,7 +312,7 @@ diff --git a/src/share/vm/classfile/clas
if (super_klass->is_interface()) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
-@@ -3000,6 +3131,7 @@
+@@ -3000,6 +3134,7 @@
this_klass->set_method_ordering(method_ordering());
this_klass->set_initial_method_idnum(methods->length());
this_klass->set_name(cp->klass_name_at(this_class_index));
@@ -315,11 +331,12 @@ diff --git a/src/share/vm/classfile/clas
bool _has_finalizer;
bool _has_empty_finalizer;
-@@ -203,6 +204,24 @@
+@@ -203,6 +204,25 @@
char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
+ bool has_cp_patch_at(int index) {
++ assert(AnonymousClasses, "");
+ assert(index >= 0, "oob");
+ return (_cp_patches != NULL
+ && index < _cp_patches->length()
@@ -340,7 +357,7 @@ diff --git a/src/share/vm/classfile/clas
public:
// Constructor
ClassFileParser(ClassFileStream* st) { set_stream(st); }
-@@ -218,6 +237,14 @@
+@@ -218,6 +238,14 @@
Handle class_loader,
Handle protection_domain,
symbolHandle& parsed_name,
@@ -378,7 +395,7 @@ diff --git a/src/share/vm/classfile/syst
// We don't redefine the class, so we just need to clean up whether there
// was an error or not (don't want to modify any system dictionary
-@@ -970,6 +972,29 @@
+@@ -970,6 +972,30 @@
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, parsed_name, class_loader, THREAD);
SystemDictionary_lock->notify_all();
@@ -386,6 +403,7 @@ diff --git a/src/share/vm/classfile/syst
+ }
+
+ if (host_klass.not_null() && k.not_null()) {
++ assert(AnonymousClasses, "");
+ // If it's anonymous, initialize it now, since nobody else will.
+ k->set_host_klass(host_klass());
+
@@ -460,21 +478,126 @@ diff --git a/src/share/vm/classfile/veri
current_frame->push_stack(
VerificationType::reference_type(
vmSymbols::java_lang_String()), CHECK_VERIFY(this));
+diff --git a/src/share/vm/includeDB_gc_parallel b/src/share/vm/includeDB_gc_parallel
+--- a/src/share/vm/includeDB_gc_parallel
++++ b/src/share/vm/includeDB_gc_parallel
+@@ -25,6 +25,12 @@
+ collectorPolicy.cpp cmsGCAdaptivePolicyCounters.hpp
+
+ compiledICHolderKlass.cpp oop.pcgc.inline.hpp
++
++constantPoolKlass.cpp cardTableRS.hpp
++constantPoolKlass.cpp oop.pcgc.inline.hpp
++constantPoolKlass.cpp psPromotionManager.inline.hpp
++constantPoolKlass.cpp psScavenge.inline.hpp
++constantPoolKlass.cpp parOopClosures.inline.hpp
+
+ genCollectedHeap.cpp concurrentMarkSweepThread.hpp
+ genCollectedHeap.cpp vmCMSOperations.hpp
diff --git a/src/share/vm/oops/constantPoolKlass.cpp b/src/share/vm/oops/constantPoolKlass.cpp
--- a/src/share/vm/oops/constantPoolKlass.cpp
+++ b/src/share/vm/oops/constantPoolKlass.cpp
-@@ -381,6 +381,7 @@
- guarantee((*base)->is_symbol() || (*base)->is_instance(),
+@@ -35,6 +35,7 @@
+ c->set_tags(NULL);
+ c->set_cache(NULL);
+ c->set_pool_holder(NULL);
++ c->set_flags(0);
+ // only set to non-zero if constant pool is merged by RedefineClasses
+ c->set_orig_length(0);
+ // all fields are initialized; needed for GC
+@@ -261,10 +262,32 @@
+
+ void constantPoolKlass::oop_copy_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->tag_at(i).is_string()) {
++ if (PSScavenge::should_scavenge(base)) {
++ pm->claim_or_forward_breadth(base);
++ }
++ }
++ }
++ }
+ }
+
+ 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->tag_at(i).is_string()) {
++ if (PSScavenge::should_scavenge(base)) {
++ pm->claim_or_forward_depth(base);
++ }
++ }
++ }
++ }
+ }
+ #endif // SERIALGC
+
+@@ -278,6 +301,12 @@
+ assert(obj->is_constantPool(), "must be constantPool");
+ Klass::oop_print_on(obj, st);
+ constantPoolOop cp = constantPoolOop(obj);
++ if (cp->flags() != 0) {
++ st->print(" - flags : 0x%x", cp->flags());
++ if (cp->has_pseudo_string()) st->print(" has_pseudo_string");
++ if (cp->has_invokedynamic()) st->print(" has_invokedynamic");
++ st->cr();
++ }
+
+ // Temp. remove cache so we can do lookups with original indicies.
+ constantPoolCacheHandle cache (THREAD, cp->cache());
+@@ -302,7 +331,7 @@
+ break;
+ case JVM_CONSTANT_UnresolvedString :
+ case JVM_CONSTANT_String :
+- anObj = cp->string_at(index, CATCH);
++ anObj = cp->pseudo_string_at(index);
+ anObj->print_value_on(st);
+ st->print(" {0x%lx}", (address)anObj);
+ break;
+@@ -382,8 +411,12 @@
"should be symbol or instance");
}
-+ if (false) // %%% pseudo strings can be in non-perm
if (cp->tag_at(i).is_string()) {
- guarantee((*base)->is_perm(), "should be in permspace");
- guarantee((*base)->is_instance(), "should be instance");
+- guarantee((*base)->is_perm(), "should be in permspace");
+- guarantee((*base)->is_instance(), "should be instance");
++ if (!cp->has_pseudo_string()) {
++ guarantee((*base)->is_perm(), "should be in permspace");
++ guarantee((*base)->is_instance(), "should be instance");
++ } else {
++ // can be non-perm, can be non-instance (array)
++ }
+ }
+ base++;
+ }
diff --git a/src/share/vm/oops/constantPoolOop.cpp b/src/share/vm/oops/constantPoolOop.cpp
--- a/src/share/vm/oops/constantPoolOop.cpp
+++ b/src/share/vm/oops/constantPoolOop.cpp
-@@ -333,8 +333,11 @@
+@@ -24,6 +24,18 @@
+
+ # include "incls/_precompiled.incl"
+ # include "incls/_constantPoolOop.cpp.incl"
++
++void constantPoolOopDesc::set_flag_at(FlagBit fb) {
++ const int MAX_STATE_CHANGES = 2;
++ for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) {
++ int oflags = _flags;
++ int nflags = oflags | (1 << (int)fb);
++ if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags)
++ return;
++ }
++ assert(false, "failed to cmpxchg flags");
++ _flags |= (1 << (int)fb); // better than nothing
++}
+
+ klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
+ // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop.
+@@ -333,8 +345,10 @@
oop entry = *(obj_at_addr(which));
if (entry->is_symbol()) {
return ((symbolOop)entry)->as_C_string();
@@ -482,26 +605,13 @@ diff --git a/src/share/vm/oops/constantP
+ return java_lang_String::as_utf8_string(entry);
} else {
- return java_lang_String::as_utf8_string(entry);
-+ assert(false, "pseudo-string");
+ return (char*)"<pseudo-string>";
}
}
-@@ -366,7 +369,7 @@
+@@ -382,6 +396,19 @@
}
- }
-
--oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
-+oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, bool pseudo_ok, TRAPS) {
- oop entry = *(this_oop->obj_at_addr(which));
- if (entry->is_symbol()) {
- ObjectLocker ol(this_oop, THREAD);
-@@ -380,8 +383,21 @@
- entry = this_oop->resolved_string_at(which);
- }
- }
-- assert(java_lang_String::is_instance(entry), "must be string");
-+ assert(pseudo_ok || java_lang_String::is_instance(entry), "must be string");
+ assert(java_lang_String::is_instance(entry), "must be string");
return entry;
+}
+
@@ -512,7 +622,7 @@ diff --git a/src/share/vm/oops/constantP
+ // Not yet resolved, but it will resolve to a string.
+ return false;
+ else if (java_lang_String::is_instance(entry))
-+ return false;
++ return false; // actually, it might be a non-interned or non-perm string
+ else
+ // truly pseudo
+ return true;
@@ -522,23 +632,69 @@ diff --git a/src/share/vm/oops/constantP
diff --git a/src/share/vm/oops/constantPoolOop.hpp b/src/share/vm/oops/constantPoolOop.hpp
--- a/src/share/vm/oops/constantPoolOop.hpp
+++ b/src/share/vm/oops/constantPoolOop.hpp
-@@ -269,7 +269,14 @@
-
- oop string_at(int which, TRAPS) {
- constantPoolHandle h_this(THREAD, this);
-- return string_at_impl(h_this, which, CHECK_NULL);
-+ return string_at_impl(h_this, which, false, CHECK_NULL);
-+ }
+@@ -41,6 +41,7 @@
+ typeArrayOop _tags; // the tag array describing the constant pool's contents
+ constantPoolCacheOop _cache; // the cache holding interpreter runtime information
+ klassOop _pool_holder; // the corresponding class
++ int _flags; // a few header bits to describe contents for GC
+ int _length; // number of elements in the array
+ // only set to non-zero if constant pool is merged by RedefineClasses
+ int _orig_length;
+@@ -48,6 +49,17 @@
+ void set_tags(typeArrayOop tags) { oop_store_without_check((oop*)&_tags, tags); }
+ void tag_at_put(int which, jbyte t) { tags()->byte_at_put(which, t); }
+ void release_tag_at_put(int which, jbyte t) { tags()->release_byte_at_put(which, t); }
++
++ enum FlagBit {
++ FB_has_invokedynamic = 1,
++ FB_has_pseudo_string = 2
++ };
++
++ int flags() const { return _flags; }
++ void set_flags(int f) { _flags = f; }
++ bool flag_at(FlagBit fb) const { return ((_flags >> (int)fb) & 1) != 0; }
++ void set_flag_at(FlagBit fb);
++ // no clear_flag_at function; they only increase
+
+ private:
+ intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); }
+@@ -81,6 +93,11 @@
+
+ public:
+ typeArrayOop tags() const { return _tags; }
++
++ bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); }
++ bool has_invokedynamic() const { return flag_at(FB_has_invokedynamic); }
++ void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); }
++ void set_invokedynamic() { set_flag_at(FB_has_invokedynamic); }
+
+ // Klass holding pool
+ klassOop pool_holder() const { return _pool_holder; }
+@@ -272,6 +289,23 @@
+ return string_at_impl(h_this, which, CHECK_NULL);
+ }
+
++ // A "pseudo string" is an non-string oop that has found is way into
++ // a String entry.
+
+ bool is_pseudo_string_at(int which);
+
-+ oop pseudo_string_at(int which, TRAPS) {
-+ constantPoolHandle h_this(THREAD, this);
-+ return string_at_impl(h_this, which, true, CHECK_NULL);
- }
-
++ oop pseudo_string_at(int which) {
++ assert(tag_at(which).is_string(), "Corrupted constant pool");
++ return *obj_at_addr(which);
++ }
++
++ void pseudo_string_at_put(int which, oop x) {
++ assert(AnonymousClasses, "");
++ set_pseudo_string(); // mark header
++ assert(tag_at(which).is_string(), "Corrupted constant pool");
++ string_at_put(which, x); // this works just fine
++ }
++
// only called when we are sure a string entry is already resolved (via an
-@@ -293,6 +300,7 @@
+ // earlier string_at call.
+ oop resolved_string_at(int which) {
+@@ -293,6 +327,7 @@
// UTF8 char* representation was chosen to avoid conversion of
// java_lang_Strings at resolved entries into symbolOops
// or vice versa.
@@ -546,15 +702,6 @@ diff --git a/src/share/vm/oops/constantP
char* string_at_noresolve(int which);
jint name_and_type_at(int which) {
-@@ -404,7 +412,7 @@
- // Implementation of methods that needs an exposed 'this' pointer, in order to
- // handle GC while executing the method
- static klassOop klass_at_impl(constantPoolHandle this_oop, int which, TRAPS);
-- static oop string_at_impl(constantPoolHandle this_oop, int which, TRAPS);
-+ static oop string_at_impl(constantPoolHandle this_oop, int which, bool pseudo_ok, TRAPS);
-
- // Resolve string constants (to prevent allocation during compilation)
- static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS);
diff --git a/src/share/vm/oops/instanceKlass.hpp b/src/share/vm/oops/instanceKlass.hpp
--- a/src/share/vm/oops/instanceKlass.hpp
+++ b/src/share/vm/oops/instanceKlass.hpp
@@ -676,7 +823,7 @@ diff --git a/src/share/vm/oops/instanceK
#endif
// Verify that klass is present in SystemDictionary
- if (ik->is_loaded()) {
-+ if (ik->is_loaded() && ik->host_klass() == NULL) { //@@@ !ik->is_anonymous()
++ if (ik->is_loaded() && !ik->is_anonymous()) {
symbolHandle h_name (thread, ik->name());
Handle h_loader (thread, ik->class_loader());
Handle h_obj(thread, obj);
@@ -693,13 +840,14 @@ diff --git a/src/share/vm/oops/klass.cpp
diff --git a/src/share/vm/oops/klass.cpp b/src/share/vm/oops/klass.cpp
--- a/src/share/vm/oops/klass.cpp
+++ b/src/share/vm/oops/klass.cpp
-@@ -478,6 +478,23 @@
+@@ -478,6 +478,24 @@
const char* Klass::external_name() const {
+ if (oop_is_instance()) {
+ instanceKlass* ik = (instanceKlass*) this;
-+ if (ik->host_klass() != NULL) { // @@@ is_anonymous()
++ if (ik->is_anonymous()) {
++ assert(AnonymousClasses, "");
+ intptr_t hash = ik->java_mirror()->identity_hash();
+ char hash_buf[40];
+ sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
@@ -707,7 +855,7 @@ diff --git a/src/share/vm/oops/klass.cpp
+
+ size_t result_len = name()->utf8_length();
+ char* result = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
-+ name()->as_klass_external_name(result, result_len + 1);
++ name()->as_klass_external_name(result, (int) result_len + 1);
+ assert(strlen(result) == result_len, "");
+ strcpy(result + result_len, hash_buf);
+ assert(strlen(result) == result_len + hash_len, "");
@@ -883,7 +1031,7 @@ diff --git a/src/share/vm/prims/unsafe.c
{CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}
};
-+JNINativeMethod dynlang_methods[] = {
++JNINativeMethod anonk_methods[] = {
+ {CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)},
+};
@@ -893,8 +1041,8 @@ diff --git a/src/share/vm/prims/unsafe.c
}
}
}
-+ {
-+ env->RegisterNatives(unsafecls, dynlang_methods, sizeof(dynlang_methods)/sizeof(JNINativeMethod));
++ if (AnonymousClasses) {
++ env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
+ if (env->ExceptionOccurred()) {
+ if (PrintMiscellaneous && (Verbose || WizardMode)) {
+ tty->print_cr("Warning: SDK 1.7 Unsafe.defineClass (anonymous version) not found.");
@@ -905,6 +1053,19 @@ diff --git a/src/share/vm/prims/unsafe.c
int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
if (env->ExceptionOccurred()) {
if (PrintMiscellaneous && (Verbose || WizardMode)) {
+diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp
+--- a/src/share/vm/runtime/globals.hpp
++++ b/src/share/vm/runtime/globals.hpp
+@@ -3181,6 +3181,9 @@
+ "Skip assert() and verify() which page-in unwanted shared " \
+ "objects. ") \
+ \
++ product(bool, AnonymousClasses, false, \
++ "support sun.misc.Unsafe.defineAnonymousClass") \
++ \
+ product(bool, TaggedStackInterpreter, false, \
+ "Insert tags in interpreter execution stack for oopmap generaion")\
+ \
diff --git a/src/share/vm/runtime/reflection.cpp b/src/share/vm/runtime/reflection.cpp
--- a/src/share/vm/runtime/reflection.cpp
+++ b/src/share/vm/runtime/reflection.cpp
--- a/meth.patch Sat Aug 30 18:16:55 2008 -0700
+++ b/meth.patch Mon Sep 01 15:49:33 2008 -0700
@@ -4203,31 +4203,6 @@ diff --git a/src/share/vm/ci/bcEscapeAna
break;
case Bytecodes::_new:
state.apush(allocated_obj);
-diff --git a/src/share/vm/ci/ciEnv.cpp b/src/share/vm/ci/ciEnv.cpp
---- a/src/share/vm/ci/ciEnv.cpp
-+++ b/src/share/vm/ci/ciEnv.cpp
-@@ -484,11 +484,16 @@
- } else if (tag.is_double()) {
- return ciConstant((jdouble)cpool->double_at(index));
- } else if (tag.is_string() || tag.is_unresolved_string()) {
-- oop string = cpool->pseudo_string_at(index, THREAD);
-- if (HAS_PENDING_EXCEPTION) {
-- CLEAR_PENDING_EXCEPTION;
-- record_out_of_memory_failure();
-- return ciConstant();
-+ oop string = NULL;
-+ if (cpool->is_pseudo_string_at(index)) {
-+ string = cpool->pseudo_string_at(index);
-+ } else {
-+ string = cpool->string_at(index, THREAD);
-+ if (HAS_PENDING_EXCEPTION) {
-+ CLEAR_PENDING_EXCEPTION;
-+ record_out_of_memory_failure();
-+ return ciConstant();
-+ }
- }
- ciObject* constant = get_object(string);
- assert (constant->is_instance(), "must be an instance, or not? ");
diff --git a/src/share/vm/ci/ciMethod.cpp b/src/share/vm/ci/ciMethod.cpp
--- a/src/share/vm/ci/ciMethod.cpp
+++ b/src/share/vm/ci/ciMethod.cpp
@@ -4390,7 +4365,7 @@ diff --git a/src/share/vm/classfile/clas
diff --git a/src/share/vm/classfile/classFileParser.cpp b/src/share/vm/classfile/classFileParser.cpp
--- a/src/share/vm/classfile/classFileParser.cpp
+++ b/src/share/vm/classfile/classFileParser.cpp
-@@ -1841,6 +1841,11 @@
+@@ -1844,6 +1844,11 @@
_has_vanilla_constructor = true;
}
@@ -4405,10 +4380,21 @@ diff --git a/src/share/vm/classfile/dict
diff --git a/src/share/vm/classfile/dictionary.cpp b/src/share/vm/classfile/dictionary.cpp
--- a/src/share/vm/classfile/dictionary.cpp
+++ b/src/share/vm/classfile/dictionary.cpp
-@@ -550,6 +550,53 @@
+@@ -549,6 +549,63 @@
+ }
}
-
++SymbolPropertyTable::SymbolPropertyTable(int table_size)
++ : Hashtable(table_size, sizeof(SymbolPropertyEntry))
++{
++}
++SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t,
++ int number_of_entries)
++ : Hashtable(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)
++{
++}
++
++
+SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash,
+ symbolHandle sym) {
+ assert(index == index_for(sym), "incorrect index?");
@@ -4455,14 +4441,13 @@ diff --git a/src/share/vm/classfile/dict
+ }
+}
+
-+
+
// ----------------------------------------------------------------------------
#ifndef PRODUCT
-
diff --git a/src/share/vm/classfile/dictionary.hpp b/src/share/vm/classfile/dictionary.hpp
--- a/src/share/vm/classfile/dictionary.hpp
+++ b/src/share/vm/classfile/dictionary.hpp
-@@ -217,3 +217,111 @@
+@@ -217,3 +217,107 @@
tty->print_cr("pd set = #%d", count);
}
};
@@ -4537,12 +4522,8 @@ diff --git a/src/share/vm/classfile/dict
+ }
+
+public:
-+ SymbolPropertyTable(int table_size)
-+ : Hashtable(table_size, sizeof(SymbolPropertyEntry))
-+ { }
-+ SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries)
-+ : Hashtable(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)
-+ { }
++ SymbolPropertyTable(int table_size);
++ SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries);
+
+ void free_entry(SymbolPropertyEntry* entry) {
+ Hashtable::free_entry(entry);
@@ -5057,7 +5038,7 @@ diff --git a/src/share/vm/classfile/syst
int SystemDictionary::_number_of_modifications = 0;
-@@ -1650,6 +1651,10 @@
+@@ -1651,6 +1652,10 @@
// represent classes we're actively loading.
placeholders_do(blk);
@@ -5068,7 +5049,7 @@ diff --git a/src/share/vm/classfile/syst
// Loader constraints. We must keep the symbolOop used in the name alive.
constraints()->always_strong_classes_do(blk);
-@@ -1684,6 +1689,10 @@
+@@ -1685,6 +1690,10 @@
// Adjust dictionary
dictionary()->oops_do(f);
@@ -5079,7 +5060,7 @@ diff --git a/src/share/vm/classfile/syst
// Partially loaded classes
placeholders()->oops_do(f);
-@@ -1757,6 +1766,8 @@
+@@ -1758,6 +1767,8 @@
void SystemDictionary::methods_do(void f(methodOop)) {
dictionary()->methods_do(f);
@@ -5088,7 +5069,7 @@ diff --git a/src/share/vm/classfile/syst
}
// ----------------------------------------------------------------------------
-@@ -1789,6 +1800,7 @@
+@@ -1790,6 +1801,7 @@
_number_of_modifications = 0;
_loader_constraints = new LoaderConstraintTable(_loader_constraint_size);
_resolution_errors = new ResolutionErrorTable(_resolution_error_size);
@@ -5096,7 +5077,7 @@ diff --git a/src/share/vm/classfile/syst
// Allocate private object used as system class loader lock
_system_loader_lock_obj = oopFactory::new_system_objArray(0, CHECK);
-@@ -1850,6 +1862,9 @@
+@@ -1851,6 +1863,9 @@
wk_klass_name_limits[0] = s;
}
}
@@ -5106,7 +5087,7 @@ diff --git a/src/share/vm/classfile/syst
}
-@@ -1882,6 +1897,12 @@
+@@ -1883,6 +1898,12 @@
instanceKlass::cast(WK_KLASS(weak_reference_klass))->set_reference_type(REF_WEAK);
instanceKlass::cast(WK_KLASS(final_reference_klass))->set_reference_type(REF_FINAL);
instanceKlass::cast(WK_KLASS(phantom_reference_klass))->set_reference_type(REF_PHANTOM);
@@ -5119,7 +5100,7 @@ diff --git a/src/share/vm/classfile/syst
initialize_wk_klasses_until(WKID_LIMIT, scan, CHECK);
-@@ -1921,6 +1942,13 @@
+@@ -1922,6 +1943,13 @@
return (BasicType)i;
}
return T_OBJECT;
@@ -5133,7 +5114,7 @@ diff --git a/src/share/vm/classfile/syst
}
// Constraints on class loaders. The details of the algorithm can be
-@@ -2133,11 +2161,56 @@
+@@ -2134,11 +2162,56 @@
}
@@ -5191,7 +5172,7 @@ diff --git a/src/share/vm/classfile/syst
char* SystemDictionary::check_signature_loaders(symbolHandle signature,
Handle loader1, Handle loader2,
bool is_method, TRAPS) {
-@@ -2158,6 +2231,224 @@
+@@ -2159,6 +2232,224 @@
sig_strm.next();
}
return NULL;
@@ -5618,6 +5599,17 @@ diff --git a/src/share/vm/classfile/vmSy
// Here are all the intrinsics known to the runtime and the CI.
+diff --git a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
+--- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
++++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
+@@ -803,6 +803,7 @@
+ if (young_gen()->is_in_reserved(addr)) {
+ assert(young_gen()->is_in(addr),
+ "addr should be in allocated part of young gen");
++ if (Debugging) return NULL; // called from find() in debug.cpp
+ Unimplemented();
+ } else if (old_gen()->is_in_reserved(addr)) {
+ assert(old_gen()->is_in(addr),
diff --git a/src/share/vm/includeDB_core b/src/share/vm/includeDB_core
--- a/src/share/vm/includeDB_core
+++ b/src/share/vm/includeDB_core
@@ -5629,7 +5621,15 @@ diff --git a/src/share/vm/includeDB_core
assembler_<arch_model>.cpp objectMonitor.hpp
assembler_<arch_model>.cpp os.hpp
assembler_<arch_model>.cpp resourceArea.hpp
-@@ -2190,6 +2191,7 @@
+@@ -1268,6 +1269,7 @@
+ cpCacheKlass.cpp collectedHeap.hpp
+ cpCacheKlass.cpp constantPoolOop.hpp
+ cpCacheKlass.cpp cpCacheKlass.hpp
++cpCacheKlass.cpp genOopClosures.inline.hpp
+ cpCacheKlass.cpp handles.inline.hpp
+ cpCacheKlass.cpp javaClasses.hpp
+ cpCacheKlass.cpp markSweep.inline.hpp
+@@ -2190,6 +2192,7 @@
interpreter_<arch_model>.cpp jvmtiExport.hpp
interpreter_<arch_model>.cpp jvmtiThreadState.hpp
interpreter_<arch_model>.cpp methodDataOop.hpp
@@ -5637,7 +5637,7 @@ diff --git a/src/share/vm/includeDB_core
interpreter_<arch_model>.cpp methodOop.hpp
interpreter_<arch_model>.cpp oop.inline.hpp
interpreter_<arch_model>.cpp sharedRuntime.hpp
-@@ -2794,6 +2796,22 @@
+@@ -2794,6 +2797,22 @@
methodDataOop.hpp orderAccess.hpp
methodDataOop.hpp universe.hpp
@@ -5660,7 +5660,7 @@ diff --git a/src/share/vm/includeDB_core
methodKlass.cpp collectedHeap.inline.hpp
methodKlass.cpp constMethodKlass.hpp
methodKlass.cpp gcLocker.hpp
-@@ -3037,6 +3055,7 @@
+@@ -3037,6 +3056,7 @@
oop.inline.hpp arrayOop.hpp
oop.inline.hpp atomic.hpp
oop.inline.hpp barrierSet.inline.hpp
@@ -5668,7 +5668,7 @@ diff --git a/src/share/vm/includeDB_core
oop.inline.hpp cardTableModRefBS.hpp
oop.inline.hpp collectedHeap.inline.hpp
oop.inline.hpp compactingPermGenGen.hpp
-@@ -3649,6 +3668,7 @@
+@@ -3649,6 +3669,7 @@
sharedRuntime.cpp interpreter.hpp
sharedRuntime.cpp javaCalls.hpp
sharedRuntime.cpp jvmtiExport.hpp
@@ -5676,7 +5676,7 @@ diff --git a/src/share/vm/includeDB_core
sharedRuntime.cpp nativeInst_<arch>.hpp
sharedRuntime.cpp nativeLookup.hpp
sharedRuntime.cpp oop.inline.hpp
-@@ -3824,6 +3844,7 @@
+@@ -3824,6 +3845,7 @@
stubGenerator_<arch_model>.cpp handles.inline.hpp
stubGenerator_<arch_model>.cpp instanceOop.hpp
stubGenerator_<arch_model>.cpp interpreter.hpp
@@ -5684,7 +5684,7 @@ diff --git a/src/share/vm/includeDB_core
stubGenerator_<arch_model>.cpp methodOop.hpp
stubGenerator_<arch_model>.cpp nativeInst_<arch>.hpp
stubGenerator_<arch_model>.cpp objArrayKlass.hpp
-@@ -4038,6 +4059,7 @@
+@@ -4038,6 +4060,7 @@
templateTable_<arch_model>.cpp interpreterRuntime.hpp
templateTable_<arch_model>.cpp interpreter.hpp
templateTable_<arch_model>.cpp methodDataOop.hpp
@@ -5695,16 +5695,16 @@ diff --git a/src/share/vm/includeDB_gc_p
diff --git a/src/share/vm/includeDB_gc_parallel b/src/share/vm/includeDB_gc_parallel
--- a/src/share/vm/includeDB_gc_parallel
+++ b/src/share/vm/includeDB_gc_parallel
-@@ -25,6 +25,12 @@
- collectorPolicy.cpp cmsGCAdaptivePolicyCounters.hpp
-
- compiledICHolderKlass.cpp oop.pcgc.inline.hpp
-+
-+constantPoolKlass.cpp cardTableRS.hpp
-+constantPoolKlass.cpp oop.pcgc.inline.hpp
-+constantPoolKlass.cpp psPromotionManager.inline.hpp
-+constantPoolKlass.cpp psScavenge.inline.hpp
-+constantPoolKlass.cpp parOopClosures.inline.hpp
+@@ -28,6 +31,12 @@
+ constantPoolKlass.cpp psPromotionManager.inline.hpp
+ constantPoolKlass.cpp psScavenge.inline.hpp
+ constantPoolKlass.cpp parOopClosures.inline.hpp
++
++cpCacheKlass.cpp cardTableRS.hpp
++cpCacheKlass.cpp oop.pcgc.inline.hpp
++cpCacheKlass.cpp psPromotionManager.inline.hpp
++cpCacheKlass.cpp psScavenge.inline.hpp
++cpCacheKlass.cpp parOopClosures.inline.hpp
genCollectedHeap.cpp concurrentMarkSweepThread.hpp
genCollectedHeap.cpp vmCMSOperations.hpp
@@ -6005,7 +6005,7 @@ diff --git a/src/share/vm/interpreter/by
+ size_t size = cache->size() * HeapWordSize;
+ size -= sizeof(constantPoolCacheOopDesc);
+ size /= sizeof(ConstantPoolCacheEntry);
-+ climit = size;
++ climit = (int) size;
+ }
+ }
+
@@ -6281,7 +6281,7 @@ diff --git a/src/share/vm/interpreter/in
if (TraceItables && Verbose) {
ResourceMark rm(thread);
tty->print_cr("Resolving: klass: %s to method: %s", info.resolved_klass()->name()->as_C_string(), info.resolved_method()->name()->as_C_string());
-@@ -660,7 +682,131 @@
+@@ -660,7 +682,133 @@
info.resolved_method(),
info.vtable_index());
}
@@ -6310,6 +6310,8 @@ diff --git a/src/share/vm/interpreter/in
+ }
+
+ constantPoolHandle pool(thread, caller_method->constants());
++ pool->set_invokedynamic(); // mark header to flag active call sites
++
+ int raw_index = four_byte_index(thread);
+ assert(constantPoolCacheOopDesc::is_secondary_index(raw_index), "invokedynamic indexes marked specially");
+
@@ -7129,72 +7131,16 @@ diff --git a/src/share/vm/memory/dump.cp
GenCollectedHeap* gch = GenCollectedHeap::heap();
// At this point, many classes have been loaded.
-diff --git a/src/share/vm/oops/constantPoolKlass.cpp b/src/share/vm/oops/constantPoolKlass.cpp
---- a/src/share/vm/oops/constantPoolKlass.cpp
-+++ b/src/share/vm/oops/constantPoolKlass.cpp
-@@ -261,10 +261,36 @@
-
- void constantPoolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
- assert(obj->is_constantPool(), "should be constant pool");
-+ constantPoolOop cp = (constantPoolOop) obj;
-+ if (MethodHandles && cp->tags() != NULL) {
-+ // FIXME: This only helps if there are pseudo-strings in this CP.
-+ // Mark such CP's with a dirty bit.
-+ oop* base = (oop*)cp->base();
-+ for (int i = 0; i < cp->length(); ++i, ++base) {
-+ if (cp->tag_at(i).is_string()) {
-+ if (PSScavenge::should_scavenge(base)) {
-+ pm->claim_or_forward_breadth(base);
-+ }
-+ }
-+ }
-+ }
- }
-
- void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
- assert(obj->is_constantPool(), "should be constant pool");
-+ constantPoolOop cp = (constantPoolOop) obj;
-+ if (MethodHandles && cp->tags() != NULL) {
-+ // FIXME: This only helps if there are pseudo-strings in this CP.
-+ // Mark such CP's with a dirty bit.
-+ oop* base = (oop*)cp->base();
-+ for (int i = 0; i < cp->length(); ++i, ++base) {
-+ if (cp->tag_at(i).is_string()) {
-+ if (PSScavenge::should_scavenge(base)) {
-+ pm->claim_or_forward_depth(base);
-+ }
-+ }
-+ }
-+ }
- }
- #endif // SERIALGC
-
-@@ -302,7 +328,7 @@
- break;
- case JVM_CONSTANT_UnresolvedString :
- case JVM_CONSTANT_String :
-- anObj = cp->string_at(index, CATCH);
-+ anObj = cp->pseudo_string_at(index);
- anObj->print_value_on(st);
- st->print(" {0x%lx}", (address)anObj);
- break;
-@@ -383,7 +409,8 @@
- }
- if (false) // %%% pseudo strings can be in non-perm
- if (cp->tag_at(i).is_string()) {
-- guarantee((*base)->is_perm(), "should be in permspace");
-+ // %%% split pseudo-string out of string
-+ //guarantee((*base)->is_perm(), "should be in permspace");
- guarantee((*base)->is_instance(), "should be instance");
- }
- base++;
diff --git a/src/share/vm/oops/constantPoolOop.cpp b/src/share/vm/oops/constantPoolOop.cpp
--- a/src/share/vm/oops/constantPoolOop.cpp
+++ b/src/share/vm/oops/constantPoolOop.cpp
-@@ -263,6 +263,18 @@
- }
-
-
+@@ -272,6 +272,18 @@
+ int constantPoolOopDesc::uncached_klass_ref_index_at(int which) {
+ jint ref_index = field_or_method_at(which, true);
+ return extract_low_short_from_int(ref_index);
++}
++
++
+
+int constantPoolOopDesc::map_instruction_operand_to_index(int operand) {
+ if (constantPoolCacheOopDesc::is_secondary_index(operand)) {
@@ -7204,69 +7150,13 @@ diff --git a/src/share/vm/oops/constantP
+ assert((int)(u2)operand == operand, "clean u2");
+ int index = Bytes::swap_u2(operand);
+ return cache()->entry_at(index)->constant_pool_index();
-+}
-+
-+
- void constantPoolOopDesc::verify_constant_pool_resolve(constantPoolHandle this_oop, KlassHandle k, TRAPS) {
- if (k->oop_is_instance() || k->oop_is_objArray()) {
- instanceKlassHandle holder (THREAD, this_oop->pool_holder());
-@@ -336,7 +348,6 @@
- } else if (java_lang_String::is_instance(entry)) {
- return java_lang_String::as_utf8_string(entry);
- } else {
-- assert(false, "pseudo-string");
- return (char*)"<pseudo-string>";
- }
}
-@@ -369,7 +380,7 @@
- }
- }
-
--oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, bool pseudo_ok, TRAPS) {
-+oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
- oop entry = *(this_oop->obj_at_addr(which));
- if (entry->is_symbol()) {
- ObjectLocker ol(this_oop, THREAD);
-@@ -383,7 +394,7 @@
- entry = this_oop->resolved_string_at(which);
- }
- }
-- assert(pseudo_ok || java_lang_String::is_instance(entry), "must be string");
-+ assert(java_lang_String::is_instance(entry), "must be string");
- return entry;
- }
+
diff --git a/src/share/vm/oops/constantPoolOop.hpp b/src/share/vm/oops/constantPoolOop.hpp
--- a/src/share/vm/oops/constantPoolOop.hpp
+++ b/src/share/vm/oops/constantPoolOop.hpp
-@@ -269,14 +269,22 @@
-
- oop string_at(int which, TRAPS) {
- constantPoolHandle h_this(THREAD, this);
-- return string_at_impl(h_this, which, false, CHECK_NULL);
-+ return string_at_impl(h_this, which, CHECK_NULL);
- }
-+
-+ // A "pseudo string" is an non-string oop that has found is way into
-+ // a String entry.
-
- bool is_pseudo_string_at(int which);
-
-- oop pseudo_string_at(int which, TRAPS) {
-- constantPoolHandle h_this(THREAD, this);
-- return string_at_impl(h_this, which, true, CHECK_NULL);
-+ oop pseudo_string_at(int which) {
-+ assert(tag_at(which).is_string(), "Corrupted constant pool");
-+ return *obj_at_addr(which);
-+ }
-+
-+ void pseudo_string_at_put(int which, oop x) {
-+ assert(tag_at(which).is_string(), "Corrupted constant pool");
-+ string_at_put(which, x); // this works just fine
- }
-
- // only called when we are sure a string entry is already resolved (via an
-@@ -384,16 +392,16 @@
+@@ -411,16 +411,16 @@
// byte order (which comes from the bytecodes after rewriting) or,
// if "uncached" is true, a vanilla constant pool index
jint field_or_method_at(int which, bool uncached) {
@@ -7288,15 +7178,57 @@ diff --git a/src/share/vm/oops/constantP
// Used while constructing constant pool (only by ClassFileParser)
jint klass_index_at(int which) {
-@@ -412,7 +420,7 @@
- // Implementation of methods that needs an exposed 'this' pointer, in order to
- // handle GC while executing the method
- static klassOop klass_at_impl(constantPoolHandle this_oop, int which, TRAPS);
-- static oop string_at_impl(constantPoolHandle this_oop, int which, bool pseudo_ok, TRAPS);
-+ static oop string_at_impl(constantPoolHandle this_oop, int which, TRAPS);
-
- // Resolve string constants (to prevent allocation during compilation)
- static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS);
+diff --git a/src/share/vm/oops/cpCacheKlass.cpp b/src/share/vm/oops/cpCacheKlass.cpp
+--- a/src/share/vm/oops/cpCacheKlass.cpp
++++ b/src/share/vm/oops/cpCacheKlass.cpp
+@@ -135,11 +135,47 @@
+ void constantPoolCacheKlass::oop_copy_contents(PSPromotionManager* pm,
+ oop obj) {
+ assert(obj->is_constantPoolCache(), "should be constant pool");
++ if (InvokeDynamic) {
++ constantPoolCacheOop cache = (constantPoolCacheOop)obj;
++ // during a scavenge, it is safe to inspect my pool, since it is perm
++ constantPoolOop pool = cache->constant_pool();
++ assert(pool->is_constantPool(), "should be constant pool");
++ if (pool->has_invokedynamic()) {
++ for (int i = 0; i < cache->length(); i++) {
++ ConstantPoolCacheEntry* e = cache->entry_at(i);
++ oop* p = (oop*)&e->_f1;
++ if (e->is_secondary_entry()) {
++ if (PSScavenge::should_scavenge(p))
++ pm->claim_or_forward_breadth(p);
++ assert(!(e->is_vfinal() && PSScavenge::should_scavenge((oop*)&e->_f2)),
++ "no live oops here");
++ }
++ }
++ }
++ }
+ }
+
+ void constantPoolCacheKlass::oop_push_contents(PSPromotionManager* pm,
+ oop obj) {
+ assert(obj->is_constantPoolCache(), "should be constant pool");
++ if (InvokeDynamic) {
++ constantPoolCacheOop cache = (constantPoolCacheOop)obj;
++ // during a scavenge, it is safe to inspect my pool, since it is perm
++ constantPoolOop pool = cache->constant_pool();
++ assert(pool->is_constantPool(), "should be constant pool");
++ if (pool->has_invokedynamic()) {
++ for (int i = 0; i < cache->length(); i++) {
++ ConstantPoolCacheEntry* e = cache->entry_at(i);
++ oop* p = (oop*)&e->_f1;
++ if (e->is_secondary_entry()) {
++ if (PSScavenge::should_scavenge(p))
++ pm->claim_or_forward_depth(p);
++ assert(!(e->is_vfinal() && PSScavenge::should_scavenge((oop*)&e->_f2)),
++ "no live oops here");
++ }
++ }
++ }
++ }
+ }
+
+ int
diff --git a/src/share/vm/oops/cpCacheOop.cpp b/src/share/vm/oops/cpCacheOop.cpp
--- a/src/share/vm/oops/cpCacheOop.cpp
+++ b/src/share/vm/oops/cpCacheOop.cpp
@@ -7377,7 +7309,16 @@ diff --git a/src/share/vm/oops/cpCacheOo
// _f2 = method/vtable index for virtual calls only, unused by all other
// calls. The vf flag indicates this is a method pointer not an
// index.
-@@ -175,6 +177,11 @@
+@@ -108,6 +110,8 @@
+
+ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
+ friend class VMStructs;
++ friend class constantPoolCacheKlass;
++
+ private:
+ volatile intx _indices; // constant pool index & rewrite bytecodes
+ volatile oop _f1; // entry specific oop field
+@@ -175,6 +179,11 @@
int index // Method index into interface
);
@@ -7389,7 +7330,7 @@ diff --git a/src/share/vm/oops/cpCacheOo
void set_parameter_size(int value) {
assert(parameter_size() == 0 || parameter_size() == value,
"size must not change");
-@@ -216,7 +223,11 @@
+@@ -216,7 +225,11 @@
}
// Accessors
@@ -7402,7 +7343,7 @@ diff --git a/src/share/vm/oops/cpCacheOo
Bytecodes::Code bytecode_1() const { return Bytecodes::cast((_indices >> 16) & 0xFF); }
Bytecodes::Code bytecode_2() const { return Bytecodes::cast((_indices >> 24) & 0xFF); }
volatile oop f1() const { return _f1; }
-@@ -311,10 +322,30 @@
+@@ -311,10 +324,30 @@
// Initialization
void initialize(intArray& inverse_index_map);
@@ -7781,18 +7722,6 @@ diff --git a/src/share/vm/oops/instanceK
OopMapBlock* map = ik->start_of_nonstatic_oop_maps();
OopMapBlock* end_map = map + ik->nonstatic_oop_map_size();
while (map < end_map) {
-diff --git a/src/share/vm/oops/klass.cpp b/src/share/vm/oops/klass.cpp
---- a/src/share/vm/oops/klass.cpp
-+++ b/src/share/vm/oops/klass.cpp
-@@ -488,7 +488,7 @@
-
- size_t result_len = name()->utf8_length();
- char* result = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
-- name()->as_klass_external_name(result, result_len + 1);
-+ name()->as_klass_external_name(result, (int) result_len + 1);
- assert(strlen(result) == result_len, "");
- strcpy(result + result_len, hash_buf);
- assert(strlen(result) == result_len + hash_len, "");
diff --git a/src/share/vm/oops/klassVtable.cpp b/src/share/vm/oops/klassVtable.cpp
--- a/src/share/vm/oops/klassVtable.cpp
+++ b/src/share/vm/oops/klassVtable.cpp
@@ -7892,7 +7821,7 @@ diff --git a/src/share/vm/oops/methodOop
set_native_function(
SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
!native_bind_event_is_interesting);
-@@ -781,6 +785,138 @@
+@@ -781,6 +785,140 @@
// caching this method should be just fine
return false;
@@ -7985,10 +7914,12 @@ diff --git a/src/share/vm/oops/methodOop
+ }
+ cp->symbol_at_put(_imcp_invoke_name, vmSymbols::invoke_name());
+ cp->symbol_at_put(_imcp_invoke_signature, signature());
-+ cp->string_at_put(_imcp_method_type_value, method_type());
-+ cp->string_at_put(_imcp_related_invoke_method, NULL);
++ cp->string_at_put(_imcp_method_type_value, vmSymbols::void_signature());
++ cp->string_at_put(_imcp_related_invoke_method, vmSymbols::void_signature());
+ cp->set_pool_holder(holder());
+
++ // set up the fancy stuff:
++ cp->pseudo_string_at_put(_imcp_method_type_value, method_type());
+ methodHandle m;
+ {
+ int flags_bits = (JVM_MH_INVOKE_BITS | JVM_ACC_PUBLIC | JVM_ACC_FINAL);
@@ -7996,7 +7927,7 @@ diff --git a/src/share/vm/oops/methodOop
+ 0, 0, 0, CHECK_(empty));
+ m = methodHandle(THREAD, m_oop);
+ }
-+ cp->string_at_put(_imcp_related_invoke_method, m());
++ cp->pseudo_string_at_put(_imcp_related_invoke_method, m());
+ m->set_constants(cp());
+ m->set_name_index(_imcp_invoke_name);
+ m->set_signature_index(_imcp_invoke_signature);
@@ -9105,7 +9036,7 @@ diff --git a/src/share/vm/runtime/argume
diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp
--- a/src/share/vm/runtime/arguments.cpp
+++ b/src/share/vm/runtime/arguments.cpp
-@@ -2508,6 +2508,13 @@
+@@ -2508,6 +2508,19 @@
}
#endif // PRODUCT
@@ -9115,27 +9046,22 @@ diff --git a/src/share/vm/runtime/argume
+ }
+ MethodHandles = true;
+ }
++ if (MethodHandles && !AnonymousClasses) {
++ if (!FLAG_IS_DEFAULT(AnonymousClasses)) {
++ warning("forcing AnonymousClasses true to support MethodHandles");
++ }
++ AnonymousClasses = true;
++ }
+
if (PrintGCDetails) {
// Turn on -verbose:gc options as well
PrintGC = true;
-diff --git a/src/share/vm/runtime/frame.hpp b/src/share/vm/runtime/frame.hpp
---- a/src/share/vm/runtime/frame.hpp
-+++ b/src/share/vm/runtime/frame.hpp
-@@ -267,7 +267,6 @@
- intptr_t* interpreter_frame_tos_at(jint offset) const;
- intptr_t* interpreter_frame_tos_address() const;
-
--
- jint interpreter_frame_expression_stack_size() const;
-
- intptr_t* interpreter_frame_sender_sp() const;
diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp
--- a/src/share/vm/runtime/globals.hpp
+++ b/src/share/vm/runtime/globals.hpp
-@@ -3181,6 +3181,18 @@
- "Skip assert() and verify() which page-in unwanted shared " \
- "objects. ") \
+@@ -3184,6 +3184,18 @@
+ product(bool, AnonymousClasses, false, \
+ "support sun.misc.Unsafe.defineAnonymousClass") \
\
+ product(bool, MethodHandles, false, \
+ "support method handles") \