changeset 1966:4110c3e0c50d

Merge
author iveresov
date Fri, 19 Nov 2010 17:01:34 -0800
parents 0be53e62c06c (diff) f264f4c42799 (current diff)
children a6b067997c7e b675ff1ca7a3
files src/share/vm/memory/universe.cpp src/share/vm/runtime/arguments.cpp
diffstat 16 files changed, 242 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Nov 18 09:52:48 2010 -0800
+++ b/.hgtags	Fri Nov 19 17:01:34 2010 -0800
@@ -128,3 +128,6 @@
 bdbc48857210a509b3c50a3291ecb9dd6a72e016 jdk7-b115
 96b3f2a7add0b445b8aa421f6823cff5a2e2fe03 jdk7-b116
 52f19c724d9634af79044a2e0defbe4a5f1adbda hs20-b02
+806d0c037e6bbb88dac0699673f4ba55ee8c02da jdk7-b117
+698b7b727e12de44139d8cca6ab9a494ead13253 jdk7-b118
+3ef7426b4deac5dcfd4afb35cabe9ab3d666df91 hs20-b02
--- a/make/hotspot_version	Thu Nov 18 09:52:48 2010 -0800
+++ b/make/hotspot_version	Fri Nov 19 17:01:34 2010 -0800
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=20
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=02
+HS_BUILD_NUMBER=03
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/src/share/vm/classfile/verifier.cpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/classfile/verifier.cpp	Fri Nov 19 17:01:34 2010 -0800
@@ -247,6 +247,10 @@
 ClassVerifier::~ClassVerifier() {
 }
 
+VerificationType ClassVerifier::object_type() const {
+  return VerificationType::reference_type(vmSymbols::java_lang_Object());
+}
+
 void ClassVerifier::verify_class(TRAPS) {
   if (_verify_verbose) {
     tty->print_cr("Verifying class %s with new format",
@@ -726,8 +730,7 @@
           }
           no_control_flow = false; break;
         case Bytecodes::_aastore :
-          type = current_frame.pop_stack(
-            VerificationType::reference_check(), CHECK_VERIFY(this));
+          type = current_frame.pop_stack(object_type(), CHECK_VERIFY(this));
           type2 = current_frame.pop_stack(
             VerificationType::integer_type(), CHECK_VERIFY(this));
           atype = current_frame.pop_stack(
@@ -1232,8 +1235,7 @@
         {
           index = bcs.get_index_u2();
           verify_cp_class_type(index, cp, CHECK_VERIFY(this));
-          current_frame.pop_stack(
-            VerificationType::reference_check(), CHECK_VERIFY(this));
+          current_frame.pop_stack(object_type(), CHECK_VERIFY(this));
           VerificationType klass_type = cp_index_to_type(
             index, cp, CHECK_VERIFY(this));
           current_frame.push_stack(klass_type, CHECK_VERIFY(this));
@@ -1242,8 +1244,7 @@
         case Bytecodes::_instanceof : {
           index = bcs.get_index_u2();
           verify_cp_class_type(index, cp, CHECK_VERIFY(this));
-          current_frame.pop_stack(
-            VerificationType::reference_check(), CHECK_VERIFY(this));
+          current_frame.pop_stack(object_type(), CHECK_VERIFY(this));
           current_frame.push_stack(
             VerificationType::integer_type(), CHECK_VERIFY(this));
           no_control_flow = false; break;
@@ -1610,9 +1611,7 @@
     verify_cp_type(index, cp, types, CHECK_VERIFY(this));
   }
   if (tag.is_string() && cp->is_pseudo_string_at(index)) {
-    current_frame->push_stack(
-      VerificationType::reference_type(
-        vmSymbols::java_lang_Object()), CHECK_VERIFY(this));
+    current_frame->push_stack(object_type(), CHECK_VERIFY(this));
   } else if (tag.is_string() || tag.is_unresolved_string()) {
     current_frame->push_stack(
       VerificationType::reference_type(
--- a/src/share/vm/classfile/verifier.hpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/classfile/verifier.hpp	Fri Nov 19 17:01:34 2010 -0800
@@ -157,6 +157,8 @@
 
   bool name_in_supers(symbolOop ref_name, instanceKlassHandle current);
 
+  VerificationType object_type() const;
+
   instanceKlassHandle _klass;  // the class being verified
   methodHandle        _method; // current method being verified
   VerificationType    _this_type; // the verification type of the current class
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Fri Nov 19 17:01:34 2010 -0800
@@ -1093,7 +1093,9 @@
 // perm_gen_verify_bit_map where we store the "deadness" information if
 // we did not sweep the perm gen in the most recent previous GC cycle.
 bool CompactibleFreeListSpace::obj_is_alive(const HeapWord* p) const {
-  assert (block_is_obj(p), "The address should point to an object");
+  assert(SafepointSynchronize::is_at_safepoint() || !is_init_completed(),
+         "Else races are possible");
+  assert(block_is_obj(p), "The address should point to an object");
 
   // If we're sweeping, we use object liveness information from the main bit map
   // for both perm gen and old gen.
@@ -1102,9 +1104,14 @@
   // main marking bit map (live_map below) is locked,
   // OR we're in other phases and perm_gen_verify_bit_map (dead_map below)
   // is stable, because it's mutated only in the sweeping phase.
+  // NOTE: This method is also used by jmap where, if class unloading is
+  // off, the results can return "false" for legitimate perm objects,
+  // when we are not in the midst of a sweeping phase, which can result
+  // in jmap not reporting certain perm gen objects. This will be moot
+  // if/when the perm gen goes away in the future.
   if (_collector->abstract_state() == CMSCollector::Sweeping) {
     CMSBitMap* live_map = _collector->markBitMap();
-    return live_map->isMarked((HeapWord*) p);
+    return live_map->par_isMarked((HeapWord*) p);
   } else {
     // If we're not currently sweeping and we haven't swept the perm gen in
     // the previous concurrent cycle then we may have dead but unswept objects
@@ -2266,7 +2273,7 @@
 }
 
 void CompactibleFreeListSpace::print() const {
-  Space::print_on(tty);
+  print_on(tty);
 }
 
 void CompactibleFreeListSpace::prepare_for_verify() {
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Nov 19 17:01:34 2010 -0800
@@ -795,6 +795,7 @@
     _worker_i(worker_i),
     _g1h(g1)
   { }
+
   bool doHeapRegion(HeapRegion* r) {
     if (!r->continuesHumongous()) {
       _cl.set_from(r);
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Nov 19 17:01:34 2010 -0800
@@ -116,7 +116,6 @@
   : _g1(g1), _conc_refine_cards(0),
     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
     _cg1r(g1->concurrent_g1_refine()),
-    _traversal_in_progress(false),
     _cset_rs_update_cl(NULL),
     _cards_scanned(NULL), _total_cards_scanned(0)
 {
@@ -512,8 +511,6 @@
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   dcqs.concatenate_logs();
 
-  assert(!_traversal_in_progress, "Invariant between iterations.");
-  set_traversal(true);
   if (ParallelGCThreads > 0) {
     _seq_task->set_n_threads((int)n_workers());
   }
@@ -539,9 +536,6 @@
 // through the oops which coincide with that card. It scans the reference
 // fields in each oop; when it finds an oop that points into the collection
 // set, the RSet for the region containing the referenced object is updated.
-// Note: _par_traversal_in_progress in the G1RemSet must be FALSE; otherwise
-// the UpdateRSetImmediate closure will cause cards to be enqueued on to
-// the DCQS that we're iterating over, causing an infinite loop.
 class UpdateRSetCardTableEntryIntoCSetClosure: public CardTableEntryClosure {
   G1CollectedHeap* _g1;
   CardTableModRefBS* _ct_bs;
@@ -611,8 +605,6 @@
   // Set all cards back to clean.
   _g1->cleanUpCardTable();
 
-  set_traversal(false);
-
   DirtyCardQueueSet& into_cset_dcqs = _g1->into_cset_dirty_card_queue_set();
   int into_cset_n_buffers = into_cset_dcqs.completed_buffers_num();
 
@@ -645,21 +637,8 @@
   assert(_g1->into_cset_dirty_card_queue_set().completed_buffers_num() == 0,
          "all buffers should be freed");
   _g1->into_cset_dirty_card_queue_set().clear_n_completed_buffers();
-
-  assert(!_traversal_in_progress, "Invariant between iterations.");
 }
 
-class UpdateRSObjectClosure: public ObjectClosure {
-  UpdateRSOopClosure* _update_rs_oop_cl;
-public:
-  UpdateRSObjectClosure(UpdateRSOopClosure* update_rs_oop_cl) :
-    _update_rs_oop_cl(update_rs_oop_cl) {}
-  void do_object(oop obj) {
-    obj->oop_iterate(_update_rs_oop_cl);
-  }
-
-};
-
 class ScrubRSClosure: public HeapRegionClosure {
   G1CollectedHeap* _g1h;
   BitMap* _region_bm;
@@ -749,7 +728,12 @@
   ct_freq_note_card(_ct_bs->index_for(start));
 #endif
 
-  UpdateRSOopClosure update_rs_oop_cl(this, worker_i);
+  assert(!check_for_refs_into_cset || _cset_rs_update_cl[worker_i] != NULL, "sanity");
+  UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1,
+                                               _g1->g1_rem_set(),
+                                               _cset_rs_update_cl[worker_i],
+                                               check_for_refs_into_cset,
+                                               worker_i);
   update_rs_oop_cl.set_from(r);
 
   TriggerClosure trigger_cl;
--- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Fri Nov 19 17:01:34 2010 -0800
@@ -59,11 +59,6 @@
   size_t*             _cards_scanned;
   size_t              _total_cards_scanned;
 
-  // _traversal_in_progress is "true" iff a traversal is in progress.
-
-  bool _traversal_in_progress;
-  void set_traversal(bool b) { _traversal_in_progress = b; }
-
   // Used for caching the closure that is responsible for scanning
   // references into the collection set.
   OopsInHeapRegionClosure** _cset_rs_update_cl;
@@ -76,10 +71,6 @@
   bool concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i,
                                     bool check_for_refs_into_cset);
 
-protected:
-  template <class T> void write_ref_nv(HeapRegion* from, T* p);
-  template <class T> void par_write_ref_nv(HeapRegion* from, T* p, int tid);
-
 public:
   // This is called to reset dual hash tables after the gc pause
   // is finished and the initial hash table is no longer being
@@ -117,22 +108,8 @@
 
   // Record, if necessary, the fact that *p (where "p" is in region "from",
   // which is required to be non-NULL) has changed to a new non-NULL value.
-  // [Below the virtual version calls a non-virtual protected
-  // workhorse that is templatified for narrow vs wide oop.]
-  inline void write_ref(HeapRegion* from, oop* p) {
-    write_ref_nv(from, p);
-  }
-  inline void write_ref(HeapRegion* from, narrowOop* p) {
-    write_ref_nv(from, p);
-  }
-  inline void par_write_ref(HeapRegion* from, oop* p, int tid) {
-    par_write_ref_nv(from, p, tid);
-  }
-  inline void par_write_ref(HeapRegion* from, narrowOop* p, int tid) {
-    par_write_ref_nv(from, p, tid);
-  }
-
-  bool self_forwarded(oop obj);
+  template <class T> void write_ref(HeapRegion* from, T* p);
+  template <class T> void par_write_ref(HeapRegion* from, T* p, int tid);
 
   // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region
   // or card, respectively, such that a region or card with a corresponding
@@ -186,9 +163,8 @@
 
 public:
   UpdateRSOopClosure(G1RemSet* rs, int worker_i = 0) :
-    _from(NULL), _rs(rs), _worker_i(worker_i) {
-    guarantee(_rs != NULL, "Requires an HRIntoG1RemSet");
-  }
+    _from(NULL), _rs(rs), _worker_i(worker_i)
+  {}
 
   void set_from(HeapRegion* from) {
     assert(from != NULL, "from region must be non-NULL");
@@ -215,3 +191,43 @@
   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
   virtual void do_oop(      oop* p) { do_oop_work(p); }
 };
+
+class UpdateRSOrPushRefOopClosure: public OopClosure {
+  G1CollectedHeap* _g1;
+  G1RemSet* _g1_rem_set;
+  HeapRegion* _from;
+  OopsInHeapRegionClosure* _push_ref_cl;
+  bool _record_refs_into_cset;
+  int _worker_i;
+
+  template <class T> void do_oop_work(T* p);
+
+public:
+  UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
+                              G1RemSet* rs,
+                              OopsInHeapRegionClosure* push_ref_cl,
+                              bool record_refs_into_cset,
+                              int worker_i = 0) :
+    _g1(g1h),
+    _g1_rem_set(rs),
+    _from(NULL),
+    _record_refs_into_cset(record_refs_into_cset),
+    _push_ref_cl(push_ref_cl),
+    _worker_i(worker_i) { }
+
+  void set_from(HeapRegion* from) {
+    assert(from != NULL, "from region must be non-NULL");
+    _from = from;
+  }
+
+  bool self_forwarded(oop obj) {
+    bool result = (obj->is_forwarded() && (obj->forwardee()== obj));
+    return result;
+  }
+
+  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
+  virtual void do_oop(oop* p)       { do_oop_work(p); }
+
+  bool apply_to_weak_ref_discovered_field() { return true; }
+};
+
--- a/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Fri Nov 19 17:01:34 2010 -0800
@@ -31,17 +31,12 @@
 }
 
 template <class T>
-inline void G1RemSet::write_ref_nv(HeapRegion* from, T* p) {
-  par_write_ref_nv(from, p, 0);
-}
-
-inline bool G1RemSet::self_forwarded(oop obj) {
-  bool result =  (obj->is_forwarded() && (obj->forwardee()== obj));
-  return result;
+inline void G1RemSet::write_ref(HeapRegion* from, T* p) {
+  par_write_ref(from, p, 0);
 }
 
 template <class T>
-inline void G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) {
+inline void G1RemSet::par_write_ref(HeapRegion* from, T* p, int tid) {
   oop obj = oopDesc::load_decode_heap_oop(p);
 #ifdef ASSERT
   // can't do because of races
@@ -62,34 +57,15 @@
   assert(from == NULL || from->is_in_reserved(p), "p is not in from");
 
   HeapRegion* to = _g1->heap_region_containing(obj);
-  // The test below could be optimized by applying a bit op to to and from.
-  if (to != NULL && from != NULL && from != to) {
-    // The _traversal_in_progress flag is true during the collection pause,
-    // false during the evacuation failure handling. This should avoid a
-    // potential loop if we were to add the card containing 'p' to the DCQS
-    // that's used to regenerate the remembered sets for the collection set,
-    // in the event of an evacuation failure, here. The UpdateRSImmediate
-    // closure will eventally call this routine.
-    if (_traversal_in_progress &&
-        to->in_collection_set() && !self_forwarded(obj)) {
-
-      assert(_cset_rs_update_cl[tid] != NULL, "should have been set already");
-      _cset_rs_update_cl[tid]->do_oop(p);
-
-      // Deferred updates to the CSet are either discarded (in the normal case),
-      // or processed (if an evacuation failure occurs) at the end
-      // of the collection.
-      // See G1RemSet::cleanup_after_oops_into_collection_set_do().
-    } else {
+  if (to != NULL && from != to) {
 #if G1_REM_SET_LOGGING
-      gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS"
-                             " for region [" PTR_FORMAT ", " PTR_FORMAT ")",
-                             p, obj,
-                             to->bottom(), to->end());
+    gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS"
+                           " for region [" PTR_FORMAT ", " PTR_FORMAT ")",
+                           p, obj,
+                           to->bottom(), to->end());
 #endif
-      assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
-      to->rem_set()->add_reference(p, tid);
-    }
+    assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
+    to->rem_set()->add_reference(p, tid);
   }
 }
 
@@ -108,3 +84,64 @@
   }
 }
 
+template <class T>
+inline void UpdateRSOrPushRefOopClosure::do_oop_work(T* p) {
+  oop obj = oopDesc::load_decode_heap_oop(p);
+#ifdef ASSERT
+  // can't do because of races
+  // assert(obj == NULL || obj->is_oop(), "expected an oop");
+
+  // Do the safe subset of is_oop
+  if (obj != NULL) {
+#ifdef CHECK_UNHANDLED_OOPS
+    oopDesc* o = obj.obj();
+#else
+    oopDesc* o = obj;
+#endif // CHECK_UNHANDLED_OOPS
+    assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
+    assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
+  }
+#endif // ASSERT
+
+  assert(_from != NULL, "from region must be non-NULL");
+
+  HeapRegion* to = _g1->heap_region_containing(obj);
+  if (to != NULL && _from != to) {
+    // The _record_refs_into_cset flag is true during the RSet
+    // updating part of an evacuation pause. It is false at all
+    // other times:
+    //  * rebuilding the rembered sets after a full GC
+    //  * during concurrent refinement.
+    //  * updating the remembered sets of regions in the collection
+    //    set in the event of an evacuation failure (when deferred
+    //    updates are enabled).
+
+    if (_record_refs_into_cset && to->in_collection_set()) {
+      // We are recording references that point into the collection
+      // set and this particular reference does exactly that...
+      // If the referenced object has already been forwarded
+      // to itself, we are handling an evacuation failure and
+      // we have already visited/tried to copy this object
+      // there is no need to retry.
+      if (!self_forwarded(obj)) {
+        assert(_push_ref_cl != NULL, "should not be null");
+        // Push the reference in the refs queue of the G1ParScanThreadState
+        // instance for this worker thread.
+        _push_ref_cl->do_oop(p);
+      }
+
+      // Deferred updates to the CSet are either discarded (in the normal case),
+      // or processed (if an evacuation failure occurs) at the end
+      // of the collection.
+      // See G1RemSet::cleanup_after_oops_into_collection_set_do().
+    } else {
+      // We either don't care about pushing references that point into the
+      // collection set (i.e. we're not during an evacuation pause) _or_
+      // the reference doesn't point into the collection set. Either way
+      // we add the reference directly to the RSet of the region containing
+      // the referenced object.
+      _g1_rem_set->par_write_ref(_from, p, _worker_i);
+    }
+  }
+}
+
--- a/src/share/vm/includeDB_core	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/includeDB_core	Fri Nov 19 17:01:34 2010 -0800
@@ -4454,6 +4454,7 @@
 universe.cpp                            generation.hpp
 universe.cpp                            handles.inline.hpp
 universe.cpp                            hashtable.inline.hpp
+universe.cpp                            init.hpp
 universe.cpp                            instanceKlass.hpp
 universe.cpp                            instanceKlassKlass.hpp
 universe.cpp                            instanceRefKlass.hpp
--- a/src/share/vm/memory/defNewGeneration.cpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/memory/defNewGeneration.cpp	Fri Nov 19 17:01:34 2010 -0800
@@ -838,7 +838,9 @@
         gch->incremental_collection_failed()) {
       seen_incremental_collection_failed = true;
     } else if (seen_incremental_collection_failed) {
-      assert(!gch->incremental_collection_failed(), "Twice in a row");
+      assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed(),
+             "Twice in a row");
+
       seen_incremental_collection_failed = false;
     }
 #endif // ASSERT
--- a/src/share/vm/memory/universe.cpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/memory/universe.cpp	Fri Nov 19 17:01:34 2010 -0800
@@ -946,6 +946,7 @@
 extern void initialize_converter_functions();
 
 bool universe_post_init() {
+  assert(!is_init_completed(), "Error: initialization not yet completed!");
   Universe::_fully_initialized = true;
   EXCEPTION_MARK;
   { ResourceMark rm;
--- a/src/share/vm/runtime/arguments.cpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/runtime/arguments.cpp	Fri Nov 19 17:01:34 2010 -0800
@@ -116,7 +116,6 @@
 // Initialize system properties key and value.
 void Arguments::init_system_properties() {
 
-  PropertyList_add(&_system_properties, new SystemProperty("java.vm.specification.version", "1.0", false));
   PropertyList_add(&_system_properties, new SystemProperty("java.vm.specification.name",
                                                                  "Java Virtual Machine Specification",  false));
   PropertyList_add(&_system_properties, new SystemProperty("java.vm.version", VM_Version::vm_release(),  false));
@@ -151,9 +150,23 @@
 
   // Update/Initialize System properties after JDK version number is known
 void Arguments::init_version_specific_system_properties() {
-  PropertyList_add(&_system_properties, new SystemProperty("java.vm.specification.vendor",
-        JDK_Version::is_gte_jdk17x_version() ? "Oracle Corporation" : "Sun Microsystems Inc.", false));
-  PropertyList_add(&_system_properties, new SystemProperty("java.vm.vendor", VM_Version::vm_vendor(),  false));
+  enum { bufsz = 16 };
+  char buffer[bufsz];
+  const char* spec_vendor = "Sun Microsystems Inc.";
+  uint32_t spec_version = 0;
+
+  if (JDK_Version::is_gte_jdk17x_version()) {
+    spec_vendor = "Oracle Corporation";
+    spec_version = JDK_Version::current().major_version();
+  }
+  jio_snprintf(buffer, bufsz, "1." UINT32_FORMAT, spec_version);
+
+  PropertyList_add(&_system_properties,
+      new SystemProperty("java.vm.specification.vendor",  spec_vendor, false));
+  PropertyList_add(&_system_properties,
+      new SystemProperty("java.vm.specification.version", buffer, false));
+  PropertyList_add(&_system_properties,
+      new SystemProperty("java.vm.vendor", VM_Version::vm_vendor(),  false));
 }
 
 /**
--- a/src/share/vm/runtime/init.cpp	Thu Nov 18 09:52:48 2010 -0800
+++ b/src/share/vm/runtime/init.cpp	Fri Nov 19 17:01:34 2010 -0800
@@ -160,5 +160,6 @@
 
 
 void set_init_completed() {
+  assert(Universe::is_fully_initialized(), "Should have completed initialization");
   _init_completed = true;
 }
--- a/test/compiler/6857159/Test6857159.java	Thu Nov 18 09:52:48 2010 -0800
+++ b/test/compiler/6857159/Test6857159.java	Fri Nov 19 17:01:34 2010 -0800
@@ -54,7 +54,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        for (int i = 0; i < 100000; i++) {
+        for (int i = 0; i < 20000; i++) {
             Thread t = null;
             switch (i % 3) {
               case 0: t = new ct0(); break;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/6981737/Test6981737.java	Fri Nov 19 17:01:34 2010 -0800
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test Test6981737.java
+ * @bug 6981737
+ * @summary check for correct vm properties
+ * @run main Test6981737
+ * @author kamg
+*/
+
+public class Test6981737 {
+
+    /**
+     * Check the 'vendor' properties java.vm.specification.version
+     * property.  Before jdk7, they should be "Sun Micro..." and "1.0".
+     * In jdk7 onwards they should be "Oracle..." and "1.<major_version>"
+     */
+    public static void main(String[] args) throws Exception {
+
+        String version = verifyProperty("java.version", "[0-9]+\\.[0-9]+\\..*");
+        String major_version_spec = version.split("\\.")[1];
+        int major_version = new Integer(major_version_spec).intValue();
+
+        String vendor_re = "Oracle Corporation";
+        String vm_spec_version_re = "1\\." + major_version_spec;
+        if (major_version < 7) {
+            vendor_re = "Sun Microsystems Inc\\.";
+            vm_spec_version_re = "1\\.0";
+        }
+        verifyProperty("java.vendor", vendor_re);
+        verifyProperty("java.vm.vendor", vendor_re);
+        verifyProperty("java.vm.specification.vendor", vendor_re);
+        verifyProperty("java.specification.vendor", vendor_re);
+        verifyProperty("java.vm.specification.version", vm_spec_version_re);
+        System.out.println("PASS");
+    }
+
+    public static String verifyProperty(String name, String expected_re) {
+        String value = System.getProperty(name, "");
+        System.out.print("Checking " + name + ": \"" + value +
+          "\".matches(\"" + expected_re + "\")... ");
+        if (!value.matches(expected_re)) {
+            System.out.println("no.");
+            throw new RuntimeException("FAIL: Wrong value for " + name +
+                " property, \"" + value + "\", expected to be of form: \"" +
+                expected_re + "\"");
+        }
+        System.out.println("yes.");
+        return value;
+    }
+}