hotspot/src/share/vm/oops/constantPoolOop.hpp
changeset 1550 be2fc37a817f
parent 670 ddf3e9583f2f
child 1894 5c343868d071
--- a/hotspot/src/share/vm/oops/constantPoolOop.hpp	Wed Nov 12 11:01:31 2008 -0800
+++ b/hotspot/src/share/vm/oops/constantPoolOop.hpp	Wed Nov 12 22:33:26 2008 -0800
@@ -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;
@@ -49,6 +50,16 @@
   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_pseudo_string = 2
+  };
+
+  int flags() const                         { return _flags; }
+  void set_flags(int f)                     { _flags = f; }
+  bool flag_at(FlagBit fb) const            { return (_flags & (1 << (int)fb)) != 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)); }
   oop* tags_addr()       { return (oop*)&_tags; }
@@ -82,6 +93,9 @@
  public:
   typeArrayOop tags() const                 { return _tags; }
 
+  bool has_pseudo_string() const            { return flag_at(FB_has_pseudo_string); }
+  void set_pseudo_string()                  {    set_flag_at(FB_has_pseudo_string); }
+
   // Klass holding pool
   klassOop pool_holder() const              { return _pool_holder; }
   void set_pool_holder(klassOop k)          { oop_store_without_check((oop*)&_pool_holder, (oop) k); }
@@ -272,6 +286,27 @@
     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.
+  // Under AnonymousClasses this can happen if the user patches a live
+  // object into a CONSTANT_String entry of an anonymous class.
+  // Method oops internally created for method handles may also
+  // use pseudo-strings to link themselves to related metaobjects.
+
+  bool is_pseudo_string_at(int which);
+
+  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() || tag_at(which).is_unresolved_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
   // earlier string_at call.
   oop resolved_string_at(int which) {
@@ -293,6 +328,7 @@
   // UTF8 char* representation was chosen to avoid conversion of
   // java_lang_Strings at resolved entries into symbolOops
   // or vice versa.
+  // Caller is responsible for checking for pseudo-strings.
   char* string_at_noresolve(int which);
 
   jint name_and_type_at(int which) {