hotspot/src/share/vm/oops/constantPoolOop.hpp

Print this page
rev 611 : Merge

@@ -1,10 +1,10 @@
 #ifdef USE_PRAGMA_IDENT_HDR
 #pragma ident "@(#)constantPoolOop.hpp  1.105 07/08/29 13:42:26 JVM"
 #endif
 /*
- * 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -35,24 +35,36 @@
 // the entry in the constant pool is a klass or String object and
 // not a symbolOop.
 
 class SymbolHashMap;
 
-class constantPoolOopDesc : public arrayOopDesc {
+class constantPoolOopDesc : public oopDesc {
   friend class VMStructs;
   friend class BytecodeInterpreter;  // Directly extracts an oop in the pool for fast instanceof/checkcast
  private:
   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;
 
   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_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; }
   oop* cache_addr()      { return (oop*)&_cache; }
 

@@ -82,10 +94,13 @@
   }
 
  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); }
   oop* pool_holder_addr()                   { return (oop*)&_pool_holder; }
 

@@ -272,10 +287,31 @@
   oop string_at(int which, TRAPS) {
     constantPoolHandle h_this(THREAD, this);
     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) {
     assert(tag_at(which).is_string(), "Corrupted constant pool");
     // Must do an acquire here in case another thread resolved the klass

@@ -293,10 +329,11 @@
 
   // Returns an UTF8 for a CONSTANT_String entry at a given index.
   // 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) {
     assert(tag_at(which).is_name_and_type(), "Corrupted constant pool");
     return *int_at_addr(which);

@@ -331,10 +368,18 @@
 
   // Klass name matches name at offset
   bool klass_name_at_matches(instanceKlassHandle k, int which);
 
   // Sizing
+  int length() const                   { return _length; }
+  void set_length(int length)          { _length = length; }
+
+  // Tells whether index is within bounds.
+  bool is_within_bounds(int index) const {
+    return 0 <= index && index < length();
+  }
+
   static int header_size()             { return sizeof(constantPoolOopDesc)/HeapWordSize; }
   static int object_size(int length)   { return align_object_size(header_size() + length); }
   int object_size()                    { return object_size(length()); }
 
   friend class constantPoolKlass;