changeset 13413:1ed9a01478b4

Merge
author lana
date Tue, 07 Aug 2012 20:23:41 -0700
parents b813248263e1 382651d28f25
children 1e161ce0b69e
files jdk/make/sunw/Makefile jdk/src/share/classes/sunw/io/Serializable.java jdk/src/share/classes/sunw/util/EventListener.java jdk/src/share/classes/sunw/util/EventObject.java jdk/src/solaris/native/java/lang/java_props_md.c
diffstat 66 files changed, 1562 insertions(+), 924 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Aug 07 12:47:45 2012 +0100
+++ b/.hgtags	Tue Aug 07 20:23:41 2012 -0700
@@ -171,3 +171,4 @@
 b820143a6f1ce993c6e6f31db4d64de990f42654 jdk8-b47
 086271e35b0a419b38e8bda9bebd70693811df0a jdk8-b48
 cecd7026f30cbd83b0601925a7a5e059aec98138 jdk8-b49
+38fe5ab028908cf64dd73a43336ba3211577bfc3 jdk8-b50
--- a/.hgtags-top-repo	Tue Aug 07 12:47:45 2012 +0100
+++ b/.hgtags-top-repo	Tue Aug 07 20:23:41 2012 -0700
@@ -171,3 +171,4 @@
 1dcb4b7b9373e64e135c12fe1f8699f1f80e51e8 jdk8-b47
 3f6c72d1c2a6e5c9e7d81c3dc984886678a128ad jdk8-b48
 c97b99424815c43818e3cc3ffcdd1a60f3198b52 jdk8-b49
+2fd67618b9a3c847780ed7b9d228e862b6e2824c jdk8-b50
--- a/corba/.hgtags	Tue Aug 07 12:47:45 2012 +0100
+++ b/corba/.hgtags	Tue Aug 07 20:23:41 2012 -0700
@@ -171,3 +171,4 @@
 21e46ea21c6a26246fb7a1926ac7fe8d580d0518 jdk8-b47
 7e2b179a5b4dbd3f097e28daa00abfcc72ba3e0b jdk8-b48
 fe44e58a6bdbeae350ce96aafb49770a5dca5d8a jdk8-b49
+d20d9eb9f093adbf392918c703960ad24c93a331 jdk8-b50
--- a/hotspot/.hgtags	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/.hgtags	Tue Aug 07 20:23:41 2012 -0700
@@ -265,3 +265,5 @@
 bd54fe36b5e50f9ef1e30a5047b27fee5297e268 hs24-b17
 e3619706a7253540a2d94e9e841acaab8ace7038 jdk8-b49
 72e0362c3f0cfacbbac8af8a5b9d2e182f21c17b hs24-b18
+58f237a9e83af6ded0d2e2c81d252cd47c0f4c45 jdk8-b50
+3b3ad16429701b2eb6712851c2f7c5a726eb2cbe hs24-b19
--- a/hotspot/make/hotspot_version	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/make/hotspot_version	Tue Aug 07 20:23:41 2012 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=24
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=18
+HS_BUILD_NUMBER=19
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/hotspot/src/os/bsd/vm/decoder_machO.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/os/bsd/vm/decoder_machO.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -26,6 +26,139 @@
 
 #ifdef __APPLE__
 #include "decoder_machO.hpp"
+
+#include <cxxabi.h>
+#include <mach-o/loader.h>
+#include <mach-o/nlist.h>
+
+
+bool MachODecoder::demangle(const char* symbol, char *buf, int buflen) {
+  int   status;
+  char* result;
+  size_t size = (size_t)buflen;
+  // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
+  // __cxa_demangle will call system "realloc" for additional memory, which
+  // may use different malloc/realloc mechanism that allocates 'buf'.
+  if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
+    jio_snprintf(buf, buflen, "%s", result);
+      // call c library's free
+      ::free(result);
+      return true;
+  }
+  return false;
+}
+
+bool MachODecoder::decode(address addr, char *buf,
+      int buflen, int *offset, const void *mach_base) {
+  struct symtab_command * symt = (struct symtab_command *)
+    mach_find_command((struct mach_header_64 *)mach_base, LC_SYMTAB);
+  if (symt == NULL) {
+    DEBUG_ONLY(tty->print_cr("no symtab in mach file at 0x%lx", mach_base));
+    return false;
+  }
+  uint32_t off = symt->symoff;          /* symbol table offset (within this mach file) */
+  uint32_t nsyms = symt->nsyms;         /* number of symbol table entries */
+  uint32_t stroff = symt->stroff;       /* string table offset */
+  uint32_t strsize = symt->strsize;     /* string table size in bytes */
+
+  // iterate through symbol table trying to match our offset
+
+  uint32_t addr_relative = (uintptr_t) mach_base - (uintptr_t) addr; // offset we seek in the symtab
+  void * symtab_addr = (void*) ((uintptr_t) mach_base + off);
+  struct nlist_64 *cur_nlist = (struct nlist_64 *) symtab_addr;
+  struct nlist_64 *last_nlist = cur_nlist;  // no size stored in an entry, so keep previously seen nlist
+
+  int32_t found_strx = 0;
+  int32_t found_symval = 0;
+
+  for (uint32_t i=0; i < nsyms; i++) {
+    uint32_t this_value = cur_nlist->n_value;
+
+    if (addr_relative == this_value) {
+      found_strx =  cur_nlist->n_un.n_strx;
+      found_symval = this_value;
+      break;
+    } else if (addr_relative > this_value) {
+      // gone past it, use previously seen nlist:
+      found_strx = last_nlist->n_un.n_strx;
+      found_symval = last_nlist->n_value;
+      break;
+    }
+    last_nlist = cur_nlist;
+    cur_nlist = cur_nlist + sizeof(struct nlist_64);
+  }
+  if (found_strx == 0) {
+    return false;
+  }
+  // write the offset:
+  *offset = addr_relative - found_symval;
+
+  // lookup found_strx in the string table
+  char * symname = mach_find_in_stringtable((char*) ((uintptr_t)mach_base + stroff), strsize, found_strx);
+  if (symname) {
+      strncpy(buf, symname, buflen);
+      return true;
+  }
+  DEBUG_ONLY(tty->print_cr("no string or null string found."));
+  return false;
+}
+
+void* MachODecoder::mach_find_command(struct mach_header_64 * mach_base, uint32_t command_wanted) {
+  // possibly verify it is a mach_header, use magic number.
+  // commands begin immediately after the header.
+  struct load_command *pos = (struct load_command *) mach_base + sizeof(struct mach_header_64);
+  for (uint32_t i = 0; i < mach_base->ncmds; i++) {
+    struct load_command *this_cmd = (struct load_command *) pos;
+    if (this_cmd->cmd == command_wanted) {
+       return pos;
+    }
+    int cmdsize = this_cmd->cmdsize;
+    pos += cmdsize;
+  }
+  return NULL;
+}
+
+char* MachODecoder::mach_find_in_stringtable(char *strtab, uint32_t tablesize, int strx_wanted) {
+
+  if (strx_wanted == 0) {
+    return NULL;
+  }
+  char *strtab_end = strtab + tablesize;
+
+  // find the first string, skip over the space char
+  // (or the four zero bytes we see e.g. in libclient)
+  if (*strtab == ' ') {
+      strtab++;
+      if (*strtab != 0) {
+          DEBUG_ONLY(tty->print_cr("string table has leading space but no following zero."));
+          return NULL;
+      }
+      strtab++;
+  } else {
+      if ((uint32_t) *strtab != 0) {
+          DEBUG_ONLY(tty->print_cr("string table without leading space or leading int of zero."));
+          return NULL;
+      }
+      strtab+=4;
+  }
+  // read the real strings starting at index 1
+  int cur_strx = 1;
+  while (strtab < strtab_end) {
+    if (cur_strx == strx_wanted) {
+        return strtab;
+    }
+    // find start of next string
+    while (*strtab != 0) {
+        strtab++;
+    }
+    strtab++; // skip the terminating zero
+    cur_strx++;
+  }
+  DEBUG_ONLY(tty->print_cr("string number %d not found.", strx_wanted));
+  return NULL;
+}
+
+
 #endif
 
 
--- a/hotspot/src/os/bsd/vm/decoder_machO.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/os/bsd/vm/decoder_machO.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -31,10 +31,25 @@
 
 // Just a placehold for now, a real implementation should derive
 // from AbstractDecoder
-class MachODecoder : public NullDecoder {
-public:
+class MachODecoder : public AbstractDecoder {
+ public:
   MachODecoder() { }
   ~MachODecoder() { }
+  virtual bool can_decode_C_frame_in_vm() const {
+    return true;
+  }
+  virtual bool demangle(const char* symbol, char* buf, int buflen);
+  virtual bool decode(address pc, char* buf, int buflen, int* offset,
+                      const void* base);
+  virtual bool decode(address pc, char* buf, int buflen, int* offset,
+                      const char* module_path = NULL) {
+    ShouldNotReachHere();
+    return false;
+  }
+
+ private:
+  void * mach_find_command(struct mach_header_64 * mach_base, uint32_t command_wanted);
+  char * mach_find_in_stringtable(char *strtab, uint32_t tablesize, int strx_wanted);
 };
 
 #endif
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -1946,10 +1946,16 @@
   return false;
 }
 
+
+#define MACH_MAXSYMLEN 256
+
 bool os::dll_address_to_function_name(address addr, char *buf,
                                       int buflen, int *offset) {
   Dl_info dlinfo;
-
+  char localbuf[MACH_MAXSYMLEN];
+
+  // dladdr will find names of dynamic functions only, but does
+  // it set dli_fbase with mach_header address when it "fails" ?
   if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) {
     if (buf != NULL) {
       if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
@@ -1965,6 +1971,14 @@
     }
   }
 
+  // Handle non-dymanic manually:
+  if (dlinfo.dli_fbase != NULL &&
+      Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset, dlinfo.dli_fbase)) {
+    if(!Decoder::demangle(localbuf, buf, buflen)) {
+      jio_snprintf(buf, buflen, "%s", localbuf);
+    }
+    return true;
+  }
   if (buf != NULL) buf[0] = '\0';
   if (offset != NULL) *offset = -1;
   return false;
--- a/hotspot/src/os/windows/vm/decoder_windows.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/os/windows/vm/decoder_windows.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -72,10 +72,10 @@
 
      // find out if jvm.dll contains private symbols, by decoding
      // current function and comparing the result
-     address addr = (address)Decoder::decode;
+     address addr = (address)Decoder::demangle;
      char buf[MAX_PATH];
      if (decode(addr, buf, sizeof(buf), NULL)) {
-       _can_decode_in_vm = !strcmp(buf, "Decoder::decode");
+       _can_decode_in_vm = !strcmp(buf, "Decoder::demangle");
      }
   }
 }
--- a/hotspot/src/os/windows/vm/decoder_windows.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/os/windows/vm/decoder_windows.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -45,6 +45,10 @@
   bool can_decode_C_frame_in_vm() const;
   bool demangle(const char* symbol, char *buf, int buflen);
   bool decode(address addr, char *buf, int buflen, int* offset, const char* modulepath = NULL);
+  bool decode(address addr, char *buf, int buflen, int* offset, const void* base) {
+    ShouldNotReachHere();
+    return false;
+  }
 
 private:
   void initialize();
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -153,4 +153,47 @@
   void verify() PRODUCT_RETURN;
 };
 
+class CSetChooserParUpdater : public StackObj {
+private:
+  CollectionSetChooser* _chooser;
+  bool _parallel;
+  uint _chunk_size;
+  uint _cur_chunk_idx;
+  uint _cur_chunk_end;
+  uint _regions_added;
+  size_t _reclaimable_bytes_added;
+
+public:
+  CSetChooserParUpdater(CollectionSetChooser* chooser,
+                        bool parallel, uint chunk_size) :
+    _chooser(chooser), _parallel(parallel), _chunk_size(chunk_size),
+    _cur_chunk_idx(0), _cur_chunk_end(0),
+    _regions_added(0), _reclaimable_bytes_added(0) { }
+
+  ~CSetChooserParUpdater() {
+    if (_parallel && _regions_added > 0) {
+      _chooser->update_totals(_regions_added, _reclaimable_bytes_added);
+    }
+  }
+
+  void add_region(HeapRegion* hr) {
+    if (_parallel) {
+      if (_cur_chunk_idx == _cur_chunk_end) {
+        _cur_chunk_idx = _chooser->claim_array_chunk(_chunk_size);
+        _cur_chunk_end = _cur_chunk_idx + _chunk_size;
+      }
+      assert(_cur_chunk_idx < _cur_chunk_end, "invariant");
+      _chooser->set_region(_cur_chunk_idx, hr);
+      _cur_chunk_idx += 1;
+    } else {
+      _chooser->add_region(hr);
+    }
+    _regions_added += 1;
+    _reclaimable_bytes_added += hr->reclaimable_bytes();
+  }
+
+  bool should_add(HeapRegion* hr) { return _chooser->should_add(hr); }
+};
+
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP
+
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -1226,9 +1226,7 @@
     } else {
       // Starts humongous case: calculate how many regions are part of
       // this humongous region and then set the bit range.
-      G1CollectedHeap* g1h = G1CollectedHeap::heap();
-      HeapRegion *last_hr = g1h->heap_region_containing_raw(hr->end() - 1);
-      BitMap::idx_t end_index = (BitMap::idx_t) last_hr->hrs_index() + 1;
+      BitMap::idx_t end_index = (BitMap::idx_t) hr->last_hc_index();
       _region_bm->par_at_put_range(index, end_index, true);
     }
   }
@@ -1645,26 +1643,27 @@
   size_t freed_bytes() { return _freed_bytes; }
 
   bool doHeapRegion(HeapRegion *hr) {
+    if (hr->continuesHumongous()) {
+      return false;
+    }
     // We use a claim value of zero here because all regions
     // were claimed with value 1 in the FinalCount task.
-    hr->reset_gc_time_stamp();
-    if (!hr->continuesHumongous()) {
-      double start = os::elapsedTime();
-      _regions_claimed++;
-      hr->note_end_of_marking();
-      _max_live_bytes += hr->max_live_bytes();
-      _g1->free_region_if_empty(hr,
-                                &_freed_bytes,
-                                _local_cleanup_list,
-                                _old_proxy_set,
-                                _humongous_proxy_set,
-                                _hrrs_cleanup_task,
-                                true /* par */);
-      double region_time = (os::elapsedTime() - start);
-      _claimed_region_time += region_time;
-      if (region_time > _max_region_time) {
-        _max_region_time = region_time;
-      }
+    _g1->reset_gc_time_stamps(hr);
+    double start = os::elapsedTime();
+    _regions_claimed++;
+    hr->note_end_of_marking();
+    _max_live_bytes += hr->max_live_bytes();
+    _g1->free_region_if_empty(hr,
+                              &_freed_bytes,
+                              _local_cleanup_list,
+                              _old_proxy_set,
+                              _humongous_proxy_set,
+                              _hrrs_cleanup_task,
+                              true /* par */);
+    double region_time = (os::elapsedTime() - start);
+    _claimed_region_time += region_time;
+    if (region_time > _max_region_time) {
+      _max_region_time = region_time;
     }
     return false;
   }
@@ -1881,6 +1880,7 @@
   } else {
     g1_par_note_end_task.work(0);
   }
+  g1h->check_gc_time_stamps();
 
   if (!cleanup_list_is_empty()) {
     // The cleanup list is not empty, so we'll have to process it
@@ -2449,24 +2449,8 @@
     } else {
       HeapRegion* hr  = _g1h->heap_region_containing(obj);
       guarantee(hr != NULL, "invariant");
-      bool over_tams = false;
-      bool marked = false;
-
-      switch (_vo) {
-        case VerifyOption_G1UsePrevMarking:
-          over_tams = hr->obj_allocated_since_prev_marking(obj);
-          marked = _g1h->isMarkedPrev(obj);
-          break;
-        case VerifyOption_G1UseNextMarking:
-          over_tams = hr->obj_allocated_since_next_marking(obj);
-          marked = _g1h->isMarkedNext(obj);
-          break;
-        case VerifyOption_G1UseMarkWord:
-          marked = obj->is_gc_marked();
-          break;
-        default:
-          ShouldNotReachHere();
-      }
+      bool over_tams = _g1h->allocated_since_marking(obj, hr, _vo);
+      bool marked = _g1h->is_marked(obj, _vo);
 
       if (over_tams) {
         str = " >";
@@ -2502,24 +2486,8 @@
     _out(out), _vo(vo), _all(all), _hr(hr) { }
 
   void do_object(oop o) {
-    bool over_tams = false;
-    bool marked = false;
-
-    switch (_vo) {
-      case VerifyOption_G1UsePrevMarking:
-        over_tams = _hr->obj_allocated_since_prev_marking(o);
-        marked = _g1h->isMarkedPrev(o);
-        break;
-      case VerifyOption_G1UseNextMarking:
-        over_tams = _hr->obj_allocated_since_next_marking(o);
-        marked = _g1h->isMarkedNext(o);
-        break;
-      case VerifyOption_G1UseMarkWord:
-        marked = o->is_gc_marked();
-        break;
-      default:
-        ShouldNotReachHere();
-    }
+    bool over_tams = _g1h->allocated_since_marking(o, _hr, _vo);
+    bool marked = _g1h->is_marked(o, _vo);
     bool print_it = _all || over_tams || marked;
 
     if (print_it) {
@@ -2533,32 +2501,17 @@
 
 class PrintReachableRegionClosure : public HeapRegionClosure {
 private:
-  outputStream* _out;
-  VerifyOption  _vo;
-  bool          _all;
+  G1CollectedHeap* _g1h;
+  outputStream*    _out;
+  VerifyOption     _vo;
+  bool             _all;
 
 public:
   bool doHeapRegion(HeapRegion* hr) {
     HeapWord* b = hr->bottom();
     HeapWord* e = hr->end();
     HeapWord* t = hr->top();
-    HeapWord* p = NULL;
-
-    switch (_vo) {
-      case VerifyOption_G1UsePrevMarking:
-        p = hr->prev_top_at_mark_start();
-        break;
-      case VerifyOption_G1UseNextMarking:
-        p = hr->next_top_at_mark_start();
-        break;
-      case VerifyOption_G1UseMarkWord:
-        // When we are verifying marking using the mark word
-        // TAMS has no relevance.
-        assert(p == NULL, "post-condition");
-        break;
-      default:
-        ShouldNotReachHere();
-    }
+    HeapWord* p = _g1h->top_at_mark_start(hr, _vo);
     _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" "
                    "TAMS: "PTR_FORMAT, b, e, t, p);
     _out->cr();
@@ -2580,20 +2533,9 @@
   PrintReachableRegionClosure(outputStream* out,
                               VerifyOption  vo,
                               bool          all) :
-    _out(out), _vo(vo), _all(all) { }
+    _g1h(G1CollectedHeap::heap()), _out(out), _vo(vo), _all(all) { }
 };
 
-static const char* verify_option_to_tams(VerifyOption vo) {
-  switch (vo) {
-    case VerifyOption_G1UsePrevMarking:
-      return "PTAMS";
-    case VerifyOption_G1UseNextMarking:
-      return "NTAMS";
-    default:
-      return "NONE";
-  }
-}
-
 void ConcurrentMark::print_reachable(const char* str,
                                      VerifyOption vo,
                                      bool all) {
@@ -2622,7 +2564,7 @@
   }
 
   outputStream* out = &fout;
-  out->print_cr("-- USING %s", verify_option_to_tams(vo));
+  out->print_cr("-- USING %s", _g1h->top_at_mark_start_str(vo));
   out->cr();
 
   out->print_cr("--- ITERATING OVER REGIONS");
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -1149,13 +1149,16 @@
 }
 
 class PostMCRemSetClearClosure: public HeapRegionClosure {
+  G1CollectedHeap* _g1h;
   ModRefBarrierSet* _mr_bs;
 public:
-  PostMCRemSetClearClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {}
+  PostMCRemSetClearClosure(G1CollectedHeap* g1h, ModRefBarrierSet* mr_bs) :
+    _g1h(g1h), _mr_bs(mr_bs) { }
   bool doHeapRegion(HeapRegion* r) {
-    r->reset_gc_time_stamp();
-    if (r->continuesHumongous())
+    if (r->continuesHumongous()) {
       return false;
+    }
+    _g1h->reset_gc_time_stamps(r);
     HeapRegionRemSet* hrrs = r->rem_set();
     if (hrrs != NULL) hrrs->clear();
     // You might think here that we could clear just the cards
@@ -1168,19 +1171,10 @@
   }
 };
 
-
-class PostMCRemSetInvalidateClosure: public HeapRegionClosure {
-  ModRefBarrierSet* _mr_bs;
-public:
-  PostMCRemSetInvalidateClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {}
-  bool doHeapRegion(HeapRegion* r) {
-    if (r->continuesHumongous()) return false;
-    if (r->used_region().word_size() != 0) {
-      _mr_bs->invalidate(r->used_region(), true /*whole heap*/);
-    }
-    return false;
-  }
-};
+void G1CollectedHeap::clear_rsets_post_compaction() {
+  PostMCRemSetClearClosure rs_clear(this, mr_bs());
+  heap_region_iterate(&rs_clear);
+}
 
 class RebuildRSOutOfRegionClosure: public HeapRegionClosure {
   G1CollectedHeap*   _g1h;
@@ -1229,7 +1223,7 @@
       if (!hr->isHumongous()) {
         _hr_printer->post_compaction(hr, G1HRPrinter::Old);
       } else if (hr->startsHumongous()) {
-        if (hr->capacity() == HeapRegion::GrainBytes) {
+        if (hr->region_num() == 1) {
           // single humongous region
           _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous);
         } else {
@@ -1247,6 +1241,11 @@
     : _hr_printer(hr_printer) { }
 };
 
+void G1CollectedHeap::print_hrs_post_compaction() {
+  PostCompactionPrinterClosure cl(hr_printer());
+  heap_region_iterate(&cl);
+}
+
 bool G1CollectedHeap::do_collection(bool explicit_gc,
                                     bool clear_all_soft_refs,
                                     size_t word_size) {
@@ -1402,8 +1401,8 @@
     // Since everything potentially moved, we will clear all remembered
     // sets, and clear all cards.  Later we will rebuild remebered
     // sets. We will also reset the GC time stamps of the regions.
-    PostMCRemSetClearClosure rs_clear(mr_bs());
-    heap_region_iterate(&rs_clear);
+    clear_rsets_post_compaction();
+    check_gc_time_stamps();
 
     // Resize the heap if necessary.
     resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size);
@@ -1413,9 +1412,7 @@
       // that all the COMMIT / UNCOMMIT events are generated before
       // the end GC event.
 
-      PostCompactionPrinterClosure cl(hr_printer());
-      heap_region_iterate(&cl);
-
+      print_hrs_post_compaction();
       _hr_printer.end_gc(true /* full */, (size_t) total_collections());
     }
 
@@ -2263,6 +2260,51 @@
   return _g1_committed.byte_size();
 }
 
+void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) {
+  assert(!hr->continuesHumongous(), "pre-condition");
+  hr->reset_gc_time_stamp();
+  if (hr->startsHumongous()) {
+    uint first_index = hr->hrs_index() + 1;
+    uint last_index = hr->last_hc_index();
+    for (uint i = first_index; i < last_index; i += 1) {
+      HeapRegion* chr = region_at(i);
+      assert(chr->continuesHumongous(), "sanity");
+      chr->reset_gc_time_stamp();
+    }
+  }
+}
+
+#ifndef PRODUCT
+class CheckGCTimeStampsHRClosure : public HeapRegionClosure {
+private:
+  unsigned _gc_time_stamp;
+  bool _failures;
+
+public:
+  CheckGCTimeStampsHRClosure(unsigned gc_time_stamp) :
+    _gc_time_stamp(gc_time_stamp), _failures(false) { }
+
+  virtual bool doHeapRegion(HeapRegion* hr) {
+    unsigned region_gc_time_stamp = hr->get_gc_time_stamp();
+    if (_gc_time_stamp != region_gc_time_stamp) {
+      gclog_or_tty->print_cr("Region "HR_FORMAT" has GC time stamp = %d, "
+                             "expected %d", HR_FORMAT_PARAMS(hr),
+                             region_gc_time_stamp, _gc_time_stamp);
+      _failures = true;
+    }
+    return false;
+  }
+
+  bool failures() { return _failures; }
+};
+
+void G1CollectedHeap::check_gc_time_stamps() {
+  CheckGCTimeStampsHRClosure cl(_gc_time_stamp);
+  heap_region_iterate(&cl);
+  guarantee(!cl.failures(), "all GC time stamps should have been reset");
+}
+#endif // PRODUCT
+
 void G1CollectedHeap::iterate_dirty_card_closure(CardTableEntryClosure* cl,
                                                  DirtyCardQueue* into_cset_dcq,
                                                  bool concurrent,
@@ -2530,7 +2572,7 @@
   IterateOopClosureRegionClosure(MemRegion mr, OopClosure* cl)
     : _mr(mr), _cl(cl) {}
   bool doHeapRegion(HeapRegion* r) {
-    if (! r->continuesHumongous()) {
+    if (!r->continuesHumongous()) {
       r->oop_iterate(_cl);
     }
     return false;
@@ -2601,14 +2643,9 @@
   _hrs.iterate(cl);
 }
 
-void G1CollectedHeap::heap_region_iterate_from(HeapRegion* r,
-                                               HeapRegionClosure* cl) const {
-  _hrs.iterate_from(r, cl);
-}
-
 void
 G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl,
-                                                 uint worker,
+                                                 uint worker_id,
                                                  uint no_of_par_workers,
                                                  jint claim_value) {
   const uint regions = n_regions();
@@ -2619,7 +2656,9 @@
          no_of_par_workers == workers()->total_workers(),
          "Non dynamic should use fixed number of workers");
   // try to spread out the starting points of the workers
-  const uint start_index = regions / max_workers * worker;
+  const HeapRegion* start_hr =
+                        start_region_for_worker(worker_id, no_of_par_workers);
+  const uint start_index = start_hr->hrs_index();
 
   // each worker will actually look at all regions
   for (uint count = 0; count < regions; ++count) {
@@ -2861,6 +2900,17 @@
   return result;
 }
 
+HeapRegion* G1CollectedHeap::start_region_for_worker(uint worker_i,
+                                                     uint no_of_par_workers) {
+  uint worker_num =
+           G1CollectedHeap::use_parallel_gc_threads() ? no_of_par_workers : 1U;
+  assert(UseDynamicNumberOfGCThreads ||
+         no_of_par_workers == workers()->total_workers(),
+         "Non dynamic should use fixed number of workers");
+  const uint start_index = n_regions() * worker_i / worker_num;
+  return region_at(start_index);
+}
+
 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) {
   HeapRegion* r = g1_policy()->collection_set();
   while (r != NULL) {
@@ -2974,6 +3024,51 @@
   g1_rem_set()->prepare_for_verify();
 }
 
+bool G1CollectedHeap::allocated_since_marking(oop obj, HeapRegion* hr,
+                                              VerifyOption vo) {
+  switch (vo) {
+  case VerifyOption_G1UsePrevMarking:
+    return hr->obj_allocated_since_prev_marking(obj);
+  case VerifyOption_G1UseNextMarking:
+    return hr->obj_allocated_since_next_marking(obj);
+  case VerifyOption_G1UseMarkWord:
+    return false;
+  default:
+    ShouldNotReachHere();
+  }
+  return false; // keep some compilers happy
+}
+
+HeapWord* G1CollectedHeap::top_at_mark_start(HeapRegion* hr, VerifyOption vo) {
+  switch (vo) {
+  case VerifyOption_G1UsePrevMarking: return hr->prev_top_at_mark_start();
+  case VerifyOption_G1UseNextMarking: return hr->next_top_at_mark_start();
+  case VerifyOption_G1UseMarkWord:    return NULL;
+  default:                            ShouldNotReachHere();
+  }
+  return NULL; // keep some compilers happy
+}
+
+bool G1CollectedHeap::is_marked(oop obj, VerifyOption vo) {
+  switch (vo) {
+  case VerifyOption_G1UsePrevMarking: return isMarkedPrev(obj);
+  case VerifyOption_G1UseNextMarking: return isMarkedNext(obj);
+  case VerifyOption_G1UseMarkWord:    return obj->is_gc_marked();
+  default:                            ShouldNotReachHere();
+  }
+  return false; // keep some compilers happy
+}
+
+const char* G1CollectedHeap::top_at_mark_start_str(VerifyOption vo) {
+  switch (vo) {
+  case VerifyOption_G1UsePrevMarking: return "PTAMS";
+  case VerifyOption_G1UseNextMarking: return "NTAMS";
+  case VerifyOption_G1UseMarkWord:    return "NONE";
+  default:                            ShouldNotReachHere();
+  }
+  return NULL; // keep some compilers happy
+}
+
 class VerifyLivenessOopClosure: public OopClosure {
   G1CollectedHeap* _g1h;
   VerifyOption _vo;
@@ -3061,9 +3156,9 @@
 
 class VerifyRegionClosure: public HeapRegionClosure {
 private:
-  bool         _par;
-  VerifyOption _vo;
-  bool         _failures;
+  bool             _par;
+  VerifyOption     _vo;
+  bool             _failures;
 public:
   // _vo == UsePrevMarking -> use "prev" marking information,
   // _vo == UseNextMarking -> use "next" marking information,
@@ -3078,8 +3173,6 @@
   }
 
   bool doHeapRegion(HeapRegion* r) {
-    guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue,
-              "Should be unclaimed at verify points.");
     if (!r->continuesHumongous()) {
       bool failures = false;
       r->verify(_vo, &failures);
@@ -5612,19 +5705,18 @@
   size_t hr_capacity = hr->capacity();
   size_t hr_pre_used = 0;
   _humongous_set.remove_with_proxy(hr, humongous_proxy_set);
+  // We need to read this before we make the region non-humongous,
+  // otherwise the information will be gone.
+  uint last_index = hr->last_hc_index();
   hr->set_notHumongous();
   free_region(hr, &hr_pre_used, free_list, par);
 
   uint i = hr->hrs_index() + 1;
-  uint num = 1;
-  while (i < n_regions()) {
+  while (i < last_index) {
     HeapRegion* curr_hr = region_at(i);
-    if (!curr_hr->continuesHumongous()) {
-      break;
-    }
+    assert(curr_hr->continuesHumongous(), "invariant");
     curr_hr->set_notHumongous();
     free_region(curr_hr, &hr_pre_used, free_list, par);
-    num += 1;
     i += 1;
   }
   assert(hr_pre_used == hr_used,
@@ -5732,7 +5824,6 @@
 
 void G1CollectedHeap::verify_dirty_young_regions() {
   verify_dirty_young_list(_young_list->first_region());
-  verify_dirty_young_list(_young_list->first_survivor_region());
 }
 #endif
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -375,6 +375,13 @@
   // this method will be found dead by the marking cycle).
   void allocate_dummy_regions() PRODUCT_RETURN;
 
+  // Clear RSets after a compaction. It also resets the GC time stamps.
+  void clear_rsets_post_compaction();
+
+  // If the HR printer is active, dump the state of the regions in the
+  // heap after a compaction.
+  void print_hrs_post_compaction();
+
   // These are macros so that, if the assert fires, we get the correct
   // line number, file, etc.
 
@@ -1061,11 +1068,18 @@
     clear_cset_start_regions();
   }
 
+  void check_gc_time_stamps() PRODUCT_RETURN;
+
   void increment_gc_time_stamp() {
     ++_gc_time_stamp;
     OrderAccess::fence();
   }
 
+  // Reset the given region's GC timestamp. If it's starts humongous,
+  // also reset the GC timestamp of its corresponding
+  // continues humongous regions too.
+  void reset_gc_time_stamps(HeapRegion* hr);
+
   void iterate_dirty_card_closure(CardTableEntryClosure* cl,
                                   DirtyCardQueue* into_cset_dcq,
                                   bool concurrent, int worker_i);
@@ -1302,11 +1316,6 @@
   // iteration early if the "doHeapRegion" method returns "true".
   void heap_region_iterate(HeapRegionClosure* blk) const;
 
-  // Iterate over heap regions starting with r (or the first region if "r"
-  // is NULL), in address order, terminating early if the "doHeapRegion"
-  // method returns "true".
-  void heap_region_iterate_from(HeapRegion* r, HeapRegionClosure* blk) const;
-
   // Return the region with the given index. It assumes the index is valid.
   HeapRegion* region_at(uint index) const { return _hrs.at(index); }
 
@@ -1351,6 +1360,11 @@
   // starting region for iterating over the current collection set.
   HeapRegion* start_cset_region_for_worker(int worker_i);
 
+  // This is a convenience method that is used by the
+  // HeapRegionIterator classes to calculate the starting region for
+  // each worker so that they do not all start from the same region.
+  HeapRegion* start_region_for_worker(uint worker_i, uint no_of_par_workers);
+
   // Iterate over the regions (if any) in the current collection set.
   void collection_set_iterate(HeapRegionClosure* blk);
 
@@ -1558,24 +1572,6 @@
   bool isMarkedPrev(oop obj) const;
   bool isMarkedNext(oop obj) const;
 
-  // vo == UsePrevMarking -> use "prev" marking information,
-  // vo == UseNextMarking -> use "next" marking information,
-  // vo == UseMarkWord    -> use mark word from object header
-  bool is_obj_dead_cond(const oop obj,
-                        const HeapRegion* hr,
-                        const VerifyOption vo) const {
-
-    switch (vo) {
-      case VerifyOption_G1UsePrevMarking:
-        return is_obj_dead(obj, hr);
-      case VerifyOption_G1UseNextMarking:
-        return is_obj_ill(obj, hr);
-      default:
-        assert(vo == VerifyOption_G1UseMarkWord, "must be");
-        return !obj->is_gc_marked();
-    }
-  }
-
   // Determine if an object is dead, given the object and also
   // the region to which the object belongs. An object is dead
   // iff a) it was not allocated since the last mark and b) it
@@ -1587,15 +1583,6 @@
       !isMarkedPrev(obj);
   }
 
-  // This is used when copying an object to survivor space.
-  // If the object is marked live, then we mark the copy live.
-  // If the object is allocated since the start of this mark
-  // cycle, then we mark the copy live.
-  // If the object has been around since the previous mark
-  // phase, and hasn't been marked yet during this phase,
-  // then we don't mark it, we just wait for the
-  // current marking cycle to get to it.
-
   // This function returns true when an object has been
   // around since the previous marking and hasn't yet
   // been marked during this marking.
@@ -1613,23 +1600,6 @@
   // Added if it is in permanent gen it isn't dead.
   // Added if it is NULL it isn't dead.
 
-  // vo == UsePrevMarking -> use "prev" marking information,
-  // vo == UseNextMarking -> use "next" marking information,
-  // vo == UseMarkWord    -> use mark word from object header
-  bool is_obj_dead_cond(const oop obj,
-                        const VerifyOption vo) const {
-
-    switch (vo) {
-      case VerifyOption_G1UsePrevMarking:
-        return is_obj_dead(obj);
-      case VerifyOption_G1UseNextMarking:
-        return is_obj_ill(obj);
-      default:
-        assert(vo == VerifyOption_G1UseMarkWord, "must be");
-        return !obj->is_gc_marked();
-    }
-  }
-
   bool is_obj_dead(const oop obj) const {
     const HeapRegion* hr = heap_region_containing(obj);
     if (hr == NULL) {
@@ -1652,6 +1622,42 @@
     else return is_obj_ill(obj, hr);
   }
 
+  // The methods below are here for convenience and dispatch the
+  // appropriate method depending on value of the given VerifyOption
+  // parameter. The options for that parameter are:
+  //
+  // vo == UsePrevMarking -> use "prev" marking information,
+  // vo == UseNextMarking -> use "next" marking information,
+  // vo == UseMarkWord    -> use mark word from object header
+
+  bool is_obj_dead_cond(const oop obj,
+                        const HeapRegion* hr,
+                        const VerifyOption vo) const {
+    switch (vo) {
+    case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj, hr);
+    case VerifyOption_G1UseNextMarking: return is_obj_ill(obj, hr);
+    case VerifyOption_G1UseMarkWord:    return !obj->is_gc_marked();
+    default:                            ShouldNotReachHere();
+    }
+    return false; // keep some compilers happy
+  }
+
+  bool is_obj_dead_cond(const oop obj,
+                        const VerifyOption vo) const {
+    switch (vo) {
+    case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj);
+    case VerifyOption_G1UseNextMarking: return is_obj_ill(obj);
+    case VerifyOption_G1UseMarkWord:    return !obj->is_gc_marked();
+    default:                            ShouldNotReachHere();
+    }
+    return false; // keep some compilers happy
+  }
+
+  bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo);
+  HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo);
+  bool is_marked(oop obj, VerifyOption vo);
+  const char* top_at_mark_start_str(VerifyOption vo);
+
   // The following is just to alert the verification code
   // that a full collection has occurred and that the
   // remembered sets are no longer up to date.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -1528,35 +1528,13 @@
 
 class ParKnownGarbageHRClosure: public HeapRegionClosure {
   G1CollectedHeap* _g1h;
-  CollectionSetChooser* _hrSorted;
-  uint _marked_regions_added;
-  size_t _reclaimable_bytes_added;
-  uint _chunk_size;
-  uint _cur_chunk_idx;
-  uint _cur_chunk_end; // Cur chunk [_cur_chunk_idx, _cur_chunk_end)
-
-  void get_new_chunk() {
-    _cur_chunk_idx = _hrSorted->claim_array_chunk(_chunk_size);
-    _cur_chunk_end = _cur_chunk_idx + _chunk_size;
-  }
-  void add_region(HeapRegion* r) {
-    if (_cur_chunk_idx == _cur_chunk_end) {
-      get_new_chunk();
-    }
-    assert(_cur_chunk_idx < _cur_chunk_end, "postcondition");
-    _hrSorted->set_region(_cur_chunk_idx, r);
-    _marked_regions_added++;
-    _reclaimable_bytes_added += r->reclaimable_bytes();
-    _cur_chunk_idx++;
-  }
+  CSetChooserParUpdater _cset_updater;
 
 public:
   ParKnownGarbageHRClosure(CollectionSetChooser* hrSorted,
                            uint chunk_size) :
-      _g1h(G1CollectedHeap::heap()),
-      _hrSorted(hrSorted), _chunk_size(chunk_size),
-      _marked_regions_added(0), _reclaimable_bytes_added(0),
-      _cur_chunk_idx(0), _cur_chunk_end(0) { }
+    _g1h(G1CollectedHeap::heap()),
+    _cset_updater(hrSorted, true /* parallel */, chunk_size) { }
 
   bool doHeapRegion(HeapRegion* r) {
     // Do we have any marking information for this region?
@@ -1564,14 +1542,12 @@
       // We will skip any region that's currently used as an old GC
       // alloc region (we should not consider those for collection
       // before we fill them up).
-      if (_hrSorted->should_add(r) && !_g1h->is_old_gc_alloc_region(r)) {
-        add_region(r);
+      if (_cset_updater.should_add(r) && !_g1h->is_old_gc_alloc_region(r)) {
+        _cset_updater.add_region(r);
       }
     }
     return false;
   }
-  uint marked_regions_added() { return _marked_regions_added; }
-  size_t reclaimable_bytes_added() { return _reclaimable_bytes_added; }
 };
 
 class ParKnownGarbageTask: public AbstractGangTask {
@@ -1591,10 +1567,6 @@
     _g1->heap_region_par_iterate_chunked(&parKnownGarbageCl, worker_id,
                                          _g1->workers()->active_workers(),
                                          HeapRegion::InitialClaimValue);
-    uint regions_added = parKnownGarbageCl.marked_regions_added();
-    size_t reclaimable_bytes_added =
-                                   parKnownGarbageCl.reclaimable_bytes_added();
-    _hrSorted->update_totals(regions_added, reclaimable_bytes_added);
   }
 };
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -262,18 +262,6 @@
   }
 };
 
-// Finds the first HeapRegion.
-class FindFirstRegionClosure: public HeapRegionClosure {
-  HeapRegion* _a_region;
-public:
-  FindFirstRegionClosure() : _a_region(NULL) {}
-  bool doHeapRegion(HeapRegion* r) {
-    _a_region = r;
-    return true;
-  }
-  HeapRegion* result() { return _a_region; }
-};
-
 void G1MarkSweep::mark_sweep_phase2() {
   // Now all live objects are marked, compute the new object addresses.
 
@@ -294,9 +282,8 @@
   TraceTime tm("phase 2", G1Log::fine() && Verbose, true, gclog_or_tty);
   GenMarkSweep::trace("2");
 
-  FindFirstRegionClosure cl;
-  g1h->heap_region_iterate(&cl);
-  HeapRegion *r = cl.result();
+  // find the first region
+  HeapRegion* r = g1h->region_at(0);
   CompactibleSpace* sp = r;
   if (r->isHumongous() && oop(r->bottom())->is_gc_marked()) {
     sp = r->next_compaction_space();
@@ -408,7 +395,3 @@
   g1h->heap_region_iterate(&blk);
 
 }
-
-// Local Variables: ***
-// c-indentation-style: gnu ***
-// End: ***
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -197,7 +197,6 @@
   HeapWord* _r_bottom;
   HeapWord* _r_end;
   OopClosure* _oc;
-  int _out_of_region;
 public:
   FilterOutOfRegionClosure(HeapRegion* r, OopClosure* oc);
   template <class T> void do_oop_nv(T* p);
@@ -205,7 +204,6 @@
   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
   bool apply_to_weak_ref_discovered_field() { return true; }
   bool do_header() { return false; }
-  int out_of_region() { return _out_of_region; }
 };
 
 // Closure for iterating over object fields during concurrent marking
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -29,31 +29,22 @@
 #include "gc_implementation/g1/g1CollectedHeap.hpp"
 #include "gc_implementation/g1/g1OopClosures.hpp"
 #include "gc_implementation/g1/g1RemSet.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
 
 /*
  * This really ought to be an inline function, but apparently the C++
  * compiler sometimes sees fit to ignore inline declarations.  Sigh.
  */
 
-// This must a ifdef'ed because the counting it controls is in a
-// perf-critical inner loop.
-#define FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT 0
-
 template <class T>
 inline void FilterIntoCSClosure::do_oop_nv(T* p) {
   T heap_oop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(heap_oop) &&
       _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) {
     _oc->do_oop(p);
-#if FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT
-    if (_dcto_cl != NULL)
-      _dcto_cl->incr_count();
-#endif
   }
 }
 
-#define FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT 0
-
 template <class T>
 inline void FilterOutOfRegionClosure::do_oop_nv(T* p) {
   T heap_oop = oopDesc::load_heap_oop(p);
@@ -61,9 +52,6 @@
     HeapWord* obj_hw = (HeapWord*)oopDesc::decode_heap_oop_not_null(heap_oop);
     if (obj_hw < _r_bottom || obj_hw >= _r_end) {
       _oc->do_oop(p);
-#if FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT
-      _out_of_region++;
-#endif
     }
   }
 }
@@ -182,6 +170,7 @@
 #endif // ASSERT
 
   assert(_from != NULL, "from region must be non-NULL");
+  assert(_from->is_in_reserved(p), "p is not in from");
 
   HeapRegion* to = _g1->heap_region_containing(obj);
   if (to != NULL && _from != to) {
@@ -212,14 +201,16 @@
       // 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);
+      return;
     }
+
+    // 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.
+    assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
+    to->rem_set()->add_reference(p, _worker_i);
   }
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -280,62 +280,6 @@
   _g1p->phase_times()->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
 }
 
-class CountRSSizeClosure: public HeapRegionClosure {
-  size_t _n;
-  size_t _tot;
-  size_t _max;
-  HeapRegion* _max_r;
-  enum {
-    N = 20,
-    MIN = 6
-  };
-  int _histo[N];
-public:
-  CountRSSizeClosure() : _n(0), _tot(0), _max(0), _max_r(NULL) {
-    for (int i = 0; i < N; i++) _histo[i] = 0;
-  }
-  bool doHeapRegion(HeapRegion* r) {
-    if (!r->continuesHumongous()) {
-      size_t occ = r->rem_set()->occupied();
-      _n++;
-      _tot += occ;
-      if (occ > _max) {
-        _max = occ;
-        _max_r = r;
-      }
-      // Fit it into a histo bin.
-      int s = 1 << MIN;
-      int i = 0;
-      while (occ > (size_t) s && i < (N-1)) {
-        s = s << 1;
-        i++;
-      }
-      _histo[i]++;
-    }
-    return false;
-  }
-  size_t n() { return _n; }
-  size_t tot() { return _tot; }
-  size_t mx() { return _max; }
-  HeapRegion* mxr() { return _max_r; }
-  void print_histo() {
-    int mx = N;
-    while (mx >= 0) {
-      if (_histo[mx-1] > 0) break;
-      mx--;
-    }
-    gclog_or_tty->print_cr("Number of regions with given RS sizes:");
-    gclog_or_tty->print_cr("           <= %8d   %8d", 1 << MIN, _histo[0]);
-    for (int i = 1; i < mx-1; i++) {
-      gclog_or_tty->print_cr("  %8d  - %8d   %8d",
-                    (1 << (MIN + i - 1)) + 1,
-                    1 << (MIN + i),
-                    _histo[i]);
-    }
-    gclog_or_tty->print_cr("            > %8d   %8d", (1 << (MIN+mx-2))+1, _histo[mx-1]);
-  }
-};
-
 void G1RemSet::cleanupHRRS() {
   HeapRegionRemSet::cleanup();
 }
@@ -349,17 +293,6 @@
     _cg1r->clear_and_record_card_counts();
   }
 
-  // Make this into a command-line flag...
-  if (G1RSCountHisto && (ParallelGCThreads == 0 || worker_i == 0)) {
-    CountRSSizeClosure count_cl;
-    _g1->heap_region_iterate(&count_cl);
-    gclog_or_tty->print_cr("Avg of %d RS counts is %f, max is %d, "
-                  "max region is " PTR_FORMAT,
-                  count_cl.n(), (float)count_cl.tot()/(float)count_cl.n(),
-                  count_cl.mx(), count_cl.mxr());
-    count_cl.print_histo();
-  }
-
   // We cache the value of 'oc' closure into the appropriate slot in the
   // _cset_rs_update_cl for this worker
   assert(worker_i < (int)n_workers(), "sanity");
@@ -568,8 +501,6 @@
 }
 
 
-static IntHistogram out_of_histo(50, 50);
-
 
 G1TriggerClosure::G1TriggerClosure() :
   _triggered(false) { }
@@ -671,7 +602,6 @@
       sdcq->enqueue(card_ptr);
     }
   } else {
-    out_of_histo.add_entry(filter_then_update_rs_oop_cl.out_of_region());
     _conc_refine_cards++;
   }
 
@@ -862,11 +792,6 @@
   card_repeat_count.print_on(gclog_or_tty);
 #endif
 
-  if (FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT) {
-    gclog_or_tty->print_cr("\nG1 rem-set out-of-region histogram: ");
-    gclog_or_tty->print_cr("  # of CS ptrs --> # of cards with that number.");
-    out_of_histo.print_on(gclog_or_tty);
-  }
   gclog_or_tty->print_cr("\n Concurrent RS processed %d cards",
                          _conc_refine_cards);
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
@@ -889,21 +814,24 @@
 
   HRRSStatsIter blk;
   g1->heap_region_iterate(&blk);
-  gclog_or_tty->print_cr("  Total heap region rem set sizes = " SIZE_FORMAT "K."
-                         "  Max = " SIZE_FORMAT "K.",
+  gclog_or_tty->print_cr("  Total heap region rem set sizes = "SIZE_FORMAT"K."
+                         "  Max = "SIZE_FORMAT"K.",
                          blk.total_mem_sz()/K, blk.max_mem_sz()/K);
-  gclog_or_tty->print_cr("  Static structures = " SIZE_FORMAT "K,"
-                         " free_lists = " SIZE_FORMAT "K.",
-                         HeapRegionRemSet::static_mem_size()/K,
-                         HeapRegionRemSet::fl_mem_size()/K);
-  gclog_or_tty->print_cr("    %d occupied cards represented.",
+  gclog_or_tty->print_cr("  Static structures = "SIZE_FORMAT"K,"
+                         " free_lists = "SIZE_FORMAT"K.",
+                         HeapRegionRemSet::static_mem_size() / K,
+                         HeapRegionRemSet::fl_mem_size() / K);
+  gclog_or_tty->print_cr("    "SIZE_FORMAT" occupied cards represented.",
                          blk.occupied());
-  gclog_or_tty->print_cr("    Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )"
-                         ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
-                         blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(),
-                         (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K,
-                         (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K);
-  gclog_or_tty->print_cr("    Did %d coarsenings.", HeapRegionRemSet::n_coarsenings());
+  HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
+  HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
+  gclog_or_tty->print_cr("    Max size region = "HR_FORMAT", "
+                         "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
+                         HR_FORMAT_PARAMS(max_mem_sz_region),
+                         (rem_set->mem_size() + K - 1)/K,
+                         (rem_set->occupied() + K - 1)/K);
+  gclog_or_tty->print_cr("    Did %d coarsenings.",
+                         HeapRegionRemSet::n_coarsenings());
 }
 
 void G1RemSet::prepare_for_verify() {
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -44,14 +44,11 @@
                                  CardTableModRefBS::PrecisionStyle precision,
                                  FilterKind fk) :
   ContiguousSpaceDCTOC(hr, cl, precision, NULL),
-  _hr(hr), _fk(fk), _g1(g1)
-{ }
+  _hr(hr), _fk(fk), _g1(g1) { }
 
 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r,
                                                    OopClosure* oc) :
-  _r_bottom(r->bottom()), _r_end(r->end()),
-  _oc(oc), _out_of_region(0)
-{}
+  _r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { }
 
 class VerifyLiveClosure: public OopClosure {
 private:
@@ -512,35 +509,19 @@
   assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant.");
 }
 
-class NextCompactionHeapRegionClosure: public HeapRegionClosure {
-  const HeapRegion* _target;
-  bool _target_seen;
-  HeapRegion* _last;
-  CompactibleSpace* _res;
-public:
-  NextCompactionHeapRegionClosure(const HeapRegion* target) :
-    _target(target), _target_seen(false), _res(NULL) {}
-  bool doHeapRegion(HeapRegion* cur) {
-    if (_target_seen) {
-      if (!cur->isHumongous()) {
-        _res = cur;
-        return true;
-      }
-    } else if (cur == _target) {
-      _target_seen = true;
+CompactibleSpace* HeapRegion::next_compaction_space() const {
+  // We're not using an iterator given that it will wrap around when
+  // it reaches the last region and this is not what we want here.
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  uint index = hrs_index() + 1;
+  while (index < g1h->n_regions()) {
+    HeapRegion* hr = g1h->region_at(index);
+    if (!hr->isHumongous()) {
+      return hr;
     }
-    return false;
+    index += 1;
   }
-  CompactibleSpace* result() { return _res; }
-};
-
-CompactibleSpace* HeapRegion::next_compaction_space() const {
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  // cast away const-ness
-  HeapRegion* r = (HeapRegion*) this;
-  NextCompactionHeapRegionClosure blk(r);
-  g1h->heap_region_iterate_from(r, &blk);
-  return blk.result();
+  return NULL;
 }
 
 void HeapRegion::save_marks() {
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -55,7 +55,10 @@
 #define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
 #define HR_FORMAT_PARAMS(_hr_) \
                 (_hr_)->hrs_index(), \
-                (_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : "-", \
+                (_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : \
+                (_hr_)->startsHumongous() ? "HS" : \
+                (_hr_)->continuesHumongous() ? "HC" : \
+                !(_hr_)->is_empty() ? "O" : "F", \
                 (_hr_)->bottom(), (_hr_)->top(), (_hr_)->end()
 
 // sentinel value for hrs_index
@@ -173,6 +176,7 @@
   virtual HeapWord* saved_mark_word() const;
   virtual void set_saved_mark();
   void reset_gc_time_stamp() { _gc_time_stamp = 0; }
+  unsigned get_gc_time_stamp() { return _gc_time_stamp; }
 
   // See the comment above in the declaration of _pre_dummy_top for an
   // explanation of what it is.
@@ -439,6 +443,25 @@
     return _humongous_start_region;
   }
 
+  // Return the number of distinct regions that are covered by this region:
+  // 1 if the region is not humongous, >= 1 if the region is humongous.
+  uint region_num() const {
+    if (!isHumongous()) {
+      return 1U;
+    } else {
+      assert(startsHumongous(), "doesn't make sense on HC regions");
+      assert(capacity() % HeapRegion::GrainBytes == 0, "sanity");
+      return (uint) (capacity() >> HeapRegion::LogOfHRGrainBytes);
+    }
+  }
+
+  // Return the index + 1 of the last HC regions that's associated
+  // with this HS region.
+  uint last_hc_index() const {
+    assert(startsHumongous(), "don't call this otherwise");
+    return hrs_index() + region_num();
+  }
+
   // Same as Space::is_in_reserved, but will use the original size of the region.
   // The original size is different only for start humongous regions. They get
   // their _end set up to be the end of the last continues region of the
@@ -622,8 +645,8 @@
   bool is_marked() { return _prev_top_at_mark_start != bottom(); }
 
   void reset_during_compaction() {
-    guarantee( isHumongous() && startsHumongous(),
-               "should only be called for humongous regions");
+    assert(isHumongous() && startsHumongous(),
+           "should only be called for starts humongous regions");
 
     zero_marked_bytes();
     init_top_at_mark_start();
@@ -774,7 +797,7 @@
   virtual void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl);
   SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DECL)
 
-  CompactibleSpace* next_compaction_space() const;
+  virtual CompactibleSpace* next_compaction_space() const;
 
   virtual void reset_after_compaction();
 
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -34,8 +34,6 @@
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-// OtherRegionsTable
-
 class PerRegionTable: public CHeapObj<mtGC> {
   friend class OtherRegionsTable;
   friend class HeapRegionRemSetIterator;
@@ -44,20 +42,18 @@
   BitMap          _bm;
   jint            _occupied;
 
-  // next pointer for free/allocated lis
+  // next pointer for free/allocated 'all' list
   PerRegionTable* _next;
 
+  // prev pointer for the allocated 'all' list
+  PerRegionTable* _prev;
+
+  // next pointer in collision list
+  PerRegionTable * _collision_list_next;
+
+  // Global free list of PRTs
   static PerRegionTable* _free_list;
 
-#ifdef _MSC_VER
-  // For some reason even though the classes are marked as friend they are unable
-  // to access CardsPerRegion when private/protected. Only the windows c++ compiler
-  // says this Sun CC and linux gcc don't have a problem with access when private
-
-  public:
-
-#endif // _MSC_VER
-
 protected:
   // We need access in order to union things into the base table.
   BitMap* bm() { return &_bm; }
@@ -69,7 +65,8 @@
   PerRegionTable(HeapRegion* hr) :
     _hr(hr),
     _occupied(0),
-    _bm(HeapRegion::CardsPerRegion, false /* in-resource-area */)
+    _bm(HeapRegion::CardsPerRegion, false /* in-resource-area */),
+    _collision_list_next(NULL), _next(NULL), _prev(NULL)
   {}
 
   void add_card_work(CardIdx_t from_card, bool par) {
@@ -126,9 +123,13 @@
     return _occupied;
   }
 
-  void init(HeapRegion* hr) {
+  void init(HeapRegion* hr, bool clear_links_to_all_list) {
+    if (clear_links_to_all_list) {
+      set_next(NULL);
+      set_prev(NULL);
+    }
     _hr = hr;
-    _next = NULL;
+    _collision_list_next = NULL;
     _occupied = 0;
     _bm.clear();
   }
@@ -175,22 +176,25 @@
     return _bm.at(card_ind);
   }
 
-  PerRegionTable* next() const { return _next; }
-  void set_next(PerRegionTable* nxt) { _next = nxt; }
-  PerRegionTable** next_addr() { return &_next; }
-
-  static void free(PerRegionTable* prt) {
+  // Bulk-free the PRTs from prt to last, assumes that they are
+  // linked together using their _next field.
+  static void bulk_free(PerRegionTable* prt, PerRegionTable* last) {
     while (true) {
       PerRegionTable* fl = _free_list;
-      prt->set_next(fl);
-      PerRegionTable* res =
-        (PerRegionTable*)
-        Atomic::cmpxchg_ptr(prt, &_free_list, fl);
-      if (res == fl) return;
+      last->set_next(fl);
+      PerRegionTable* res = (PerRegionTable*) Atomic::cmpxchg_ptr(prt, &_free_list, fl);
+      if (res == fl) {
+        return;
+      }
     }
     ShouldNotReachHere();
   }
 
+  static void free(PerRegionTable* prt) {
+    bulk_free(prt, prt);
+  }
+
+  // Returns an initialized PerRegionTable instance.
   static PerRegionTable* alloc(HeapRegion* hr) {
     PerRegionTable* fl = _free_list;
     while (fl != NULL) {
@@ -199,7 +203,7 @@
         (PerRegionTable*)
         Atomic::cmpxchg_ptr(nxt, &_free_list, fl);
       if (res == fl) {
-        fl->init(hr);
+        fl->init(hr, true);
         return fl;
       } else {
         fl = _free_list;
@@ -209,6 +213,31 @@
     return new PerRegionTable(hr);
   }
 
+  PerRegionTable* next() const { return _next; }
+  void set_next(PerRegionTable* next) { _next = next; }
+  PerRegionTable* prev() const { return _prev; }
+  void set_prev(PerRegionTable* prev) { _prev = prev; }
+
+  // Accessor and Modification routines for the pointer for the
+  // singly linked collision list that links the PRTs within the
+  // OtherRegionsTable::_fine_grain_regions hash table.
+  //
+  // It might be useful to also make the collision list doubly linked
+  // to avoid iteration over the collisions list during scrubbing/deletion.
+  // OTOH there might not be many collisions.
+
+  PerRegionTable* collision_list_next() const {
+    return _collision_list_next;
+  }
+
+  void set_collision_list_next(PerRegionTable* next) {
+    _collision_list_next = next;
+  }
+
+  PerRegionTable** collision_list_next_addr() {
+    return &_collision_list_next;
+  }
+
   static size_t fl_mem_size() {
     PerRegionTable* cur = _free_list;
     size_t res = 0;
@@ -234,6 +263,7 @@
   _coarse_map(G1CollectedHeap::heap()->max_regions(),
               false /* in-resource-area */),
   _fine_grain_regions(NULL),
+  _first_all_fine_prts(NULL), _last_all_fine_prts(NULL),
   _n_fine_entries(0), _n_coarse_entries(0),
   _fine_eviction_start(0),
   _sparse_table(hr)
@@ -264,6 +294,66 @@
   }
 }
 
+void OtherRegionsTable::link_to_all(PerRegionTable* prt) {
+  // We always append to the beginning of the list for convenience;
+  // the order of entries in this list does not matter.
+  if (_first_all_fine_prts != NULL) {
+    assert(_first_all_fine_prts->prev() == NULL, "invariant");
+    _first_all_fine_prts->set_prev(prt);
+    prt->set_next(_first_all_fine_prts);
+  } else {
+    // this is the first element we insert. Adjust the "last" pointer
+    _last_all_fine_prts = prt;
+    assert(prt->next() == NULL, "just checking");
+  }
+  // the new element is always the first element without a predecessor
+  prt->set_prev(NULL);
+  _first_all_fine_prts = prt;
+
+  assert(prt->prev() == NULL, "just checking");
+  assert(_first_all_fine_prts == prt, "just checking");
+  assert((_first_all_fine_prts == NULL && _last_all_fine_prts == NULL) ||
+         (_first_all_fine_prts != NULL && _last_all_fine_prts != NULL),
+         "just checking");
+  assert(_last_all_fine_prts == NULL || _last_all_fine_prts->next() == NULL,
+         "just checking");
+  assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL,
+         "just checking");
+}
+
+void OtherRegionsTable::unlink_from_all(PerRegionTable* prt) {
+  if (prt->prev() != NULL) {
+    assert(_first_all_fine_prts != prt, "just checking");
+    prt->prev()->set_next(prt->next());
+    // removing the last element in the list?
+    if (_last_all_fine_prts == prt) {
+      _last_all_fine_prts = prt->prev();
+    }
+  } else {
+    assert(_first_all_fine_prts == prt, "just checking");
+    _first_all_fine_prts = prt->next();
+    // list is empty now?
+    if (_first_all_fine_prts == NULL) {
+      _last_all_fine_prts = NULL;
+    }
+  }
+
+  if (prt->next() != NULL) {
+    prt->next()->set_prev(prt->prev());
+  }
+
+  prt->set_next(NULL);
+  prt->set_prev(NULL);
+
+  assert((_first_all_fine_prts == NULL && _last_all_fine_prts == NULL) ||
+         (_first_all_fine_prts != NULL && _last_all_fine_prts != NULL),
+         "just checking");
+  assert(_last_all_fine_prts == NULL || _last_all_fine_prts->next() == NULL,
+         "just checking");
+  assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL,
+         "just checking");
+}
+
 int**  OtherRegionsTable::_from_card_cache = NULL;
 size_t OtherRegionsTable::_from_card_cache_max_regions = 0;
 size_t OtherRegionsTable::_from_card_cache_mem_size = 0;
@@ -386,13 +476,16 @@
 
       if (_n_fine_entries == _max_fine_entries) {
         prt = delete_region_table();
+        // There is no need to clear the links to the 'all' list here:
+        // prt will be reused immediately, i.e. remain in the 'all' list.
+        prt->init(from_hr, false /* clear_links_to_all_list */);
       } else {
         prt = PerRegionTable::alloc(from_hr);
+        link_to_all(prt);
       }
-      prt->init(from_hr);
 
       PerRegionTable* first_prt = _fine_grain_regions[ind];
-      prt->set_next(first_prt);  // XXX Maybe move to init?
+      prt->set_collision_list_next(first_prt);
       _fine_grain_regions[ind] = prt;
       _n_fine_entries++;
 
@@ -438,7 +531,7 @@
   assert(0 <= ind && ind < _max_fine_entries, "Preconditions.");
   PerRegionTable* prt = _fine_grain_regions[ind];
   while (prt != NULL && prt->hr() != hr) {
-    prt = prt->next();
+    prt = prt->collision_list_next();
   }
   // Loop postcondition is the method postcondition.
   return prt;
@@ -473,8 +566,8 @@
         max_ind = i;
         max_occ = cur_occ;
       }
-      prev = cur->next_addr();
-      cur = cur->next();
+      prev = cur->collision_list_next_addr();
+      cur = cur->collision_list_next();
     }
     i = i + _fine_eviction_stride;
     if (i >= _n_fine_entries) i = i - _n_fine_entries;
@@ -503,7 +596,7 @@
   }
 
   // Unsplice.
-  *max_prev = max->next();
+  *max_prev = max->collision_list_next();
   Atomic::inc(&_n_coarsenings);
   _n_fine_entries--;
   return max;
@@ -534,7 +627,7 @@
     PerRegionTable* cur = _fine_grain_regions[i];
     PerRegionTable** prev = &_fine_grain_regions[i];
     while (cur != NULL) {
-      PerRegionTable* nxt = cur->next();
+      PerRegionTable* nxt = cur->collision_list_next();
       // If the entire region is dead, eliminate.
       if (G1RSScrubVerbose) {
         gclog_or_tty->print_cr("     For other region %u:",
@@ -542,11 +635,12 @@
       }
       if (!region_bm->at((size_t) cur->hr()->hrs_index())) {
         *prev = nxt;
-        cur->set_next(NULL);
+        cur->set_collision_list_next(NULL);
         _n_fine_entries--;
         if (G1RSScrubVerbose) {
           gclog_or_tty->print_cr("          deleted via region map.");
         }
+        unlink_from_all(cur);
         PerRegionTable::free(cur);
       } else {
         // Do fine-grain elimination.
@@ -560,11 +654,12 @@
         // Did that empty the table completely?
         if (cur->occupied() == 0) {
           *prev = nxt;
-          cur->set_next(NULL);
+          cur->set_collision_list_next(NULL);
           _n_fine_entries--;
+          unlink_from_all(cur);
           PerRegionTable::free(cur);
         } else {
-          prev = cur->next_addr();
+          prev = cur->collision_list_next_addr();
         }
       }
       cur = nxt;
@@ -587,13 +682,15 @@
 
 size_t OtherRegionsTable::occ_fine() const {
   size_t sum = 0;
-  for (size_t i = 0; i < _max_fine_entries; i++) {
-    PerRegionTable* cur = _fine_grain_regions[i];
-    while (cur != NULL) {
-      sum += cur->occupied();
-      cur = cur->next();
-    }
+
+  size_t num = 0;
+  PerRegionTable * cur = _first_all_fine_prts;
+  while (cur != NULL) {
+    sum += cur->occupied();
+    cur = cur->next();
+    num++;
   }
+  guarantee(num == _n_fine_entries, "just checking");
   return sum;
 }
 
@@ -609,12 +706,10 @@
   // Cast away const in this case.
   MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag);
   size_t sum = 0;
-  for (size_t i = 0; i < _max_fine_entries; i++) {
-    PerRegionTable* cur = _fine_grain_regions[i];
-    while (cur != NULL) {
-      sum += cur->mem_size();
-      cur = cur->next();
-    }
+  PerRegionTable * cur = _first_all_fine_prts;
+  while (cur != NULL) {
+    sum += cur->mem_size();
+    cur = cur->next();
   }
   sum += (sizeof(PerRegionTable*) * _max_fine_entries);
   sum += (_coarse_map.size_in_words() * HeapWordSize);
@@ -632,22 +727,24 @@
 }
 
 void OtherRegionsTable::clear_fcc() {
+  size_t hrs_idx = hr()->hrs_index();
   for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
-    _from_card_cache[i][hr()->hrs_index()] = -1;
+    _from_card_cache[i][hrs_idx] = -1;
   }
 }
 
 void OtherRegionsTable::clear() {
   MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
-  for (size_t i = 0; i < _max_fine_entries; i++) {
-    PerRegionTable* cur = _fine_grain_regions[i];
-    while (cur != NULL) {
-      PerRegionTable* nxt = cur->next();
-      PerRegionTable::free(cur);
-      cur = nxt;
-    }
-    _fine_grain_regions[i] = NULL;
+  // if there are no entries, skip this step
+  if (_first_all_fine_prts != NULL) {
+    guarantee(_first_all_fine_prts != NULL && _last_all_fine_prts != NULL, "just checking");
+    PerRegionTable::bulk_free(_first_all_fine_prts, _last_all_fine_prts);
+    memset(_fine_grain_regions, 0, _max_fine_entries * sizeof(_fine_grain_regions[0]));
+  } else {
+    guarantee(_first_all_fine_prts == NULL && _last_all_fine_prts == NULL, "just checking");
   }
+
+  _first_all_fine_prts = _last_all_fine_prts = NULL;
   _sparse_table.clear();
   _coarse_map.clear();
   _n_fine_entries = 0;
@@ -686,12 +783,13 @@
   PerRegionTable** prev_addr = &_fine_grain_regions[ind];
   PerRegionTable* prt = *prev_addr;
   while (prt != NULL && prt->hr() != hr) {
-    prev_addr = prt->next_addr();
-    prt = prt->next();
+    prev_addr = prt->collision_list_next_addr();
+    prt = prt->collision_list_next();
   }
   if (prt != NULL) {
     assert(prt->hr() == hr, "Loop postcondition.");
-    *prev_addr = prt->next();
+    *prev_addr = prt->collision_list_next();
+    unlink_from_all(prt);
     PerRegionTable::free(prt);
     _n_fine_entries--;
     return true;
@@ -793,7 +891,6 @@
       G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
     gclog_or_tty->print_cr("  Card " PTR_FORMAT, card_start);
   }
-
   if (iter.n_yielded() != occupied()) {
     gclog_or_tty->print_cr("Yielded disagrees with occupied:");
     gclog_or_tty->print_cr("  %6d yielded (%6d coarse, %6d fine).",
@@ -905,7 +1002,7 @@
   while (!fine_has_next()) {
     if (_cur_region_cur_card == (size_t) HeapRegion::CardsPerRegion) {
       _cur_region_cur_card = 0;
-      _fine_cur_prt = _fine_cur_prt->next();
+      _fine_cur_prt = _fine_cur_prt->collision_list_next();
     }
     if (_fine_cur_prt == NULL) {
       fine_find_next_non_null_prt();
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -82,6 +82,14 @@
   PerRegionTable** _fine_grain_regions;
   size_t           _n_fine_entries;
 
+  // The fine grain remembered sets are doubly linked together using
+  // their 'next' and 'prev' fields.
+  // This allows fast bulk freeing of all the fine grain remembered
+  // set entries, and fast finding of all of them without iterating
+  // over the _fine_grain_regions table.
+  PerRegionTable * _first_all_fine_prts;
+  PerRegionTable * _last_all_fine_prts;
+
   // Used to sample a subset of the fine grain PRTs to determine which
   // PRT to evict and coarsen.
   size_t        _fine_eviction_start;
@@ -114,6 +122,11 @@
   static size_t _from_card_cache_max_regions;
   static size_t _from_card_cache_mem_size;
 
+  // link/add the given fine grain remembered set into the "all" list
+  void link_to_all(PerRegionTable * prt);
+  // unlink/remove the given fine grain remembered set into the "all" list
+  void unlink_from_all(PerRegionTable * prt);
+
 public:
   OtherRegionsTable(HeapRegion* hr);
 
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -35,14 +35,6 @@
   _unrealistically_long_length = len;
 }
 
-uint HeapRegionSetBase::calculate_region_num(HeapRegion* hr) {
-  assert(hr->startsHumongous(), "pre-condition");
-  assert(hr->capacity() % HeapRegion::GrainBytes == 0, "invariant");
-  uint region_num = (uint) (hr->capacity() >> HeapRegion::LogOfHRGrainBytes);
-  assert(region_num > 0, "sanity");
-  return region_num;
-}
-
 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
   msg->append("[%s] %s ln: %u rn: %u cy: "SIZE_FORMAT" ud: "SIZE_FORMAT,
               name(), message, length(), region_num(),
@@ -152,11 +144,7 @@
   guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification"));
 
   _calc_length               += 1;
-  if (!hr->isHumongous()) {
-    _calc_region_num         += 1;
-  } else {
-    _calc_region_num         += calculate_region_num(hr);
-  }
+  _calc_region_num           += hr->region_num();
   _calc_total_capacity_bytes += hr->capacity();
   _calc_total_used_bytes     += hr->used();
 }
@@ -292,7 +280,7 @@
     assert(length() >  0 && _tail != NULL, hrs_ext_msg(this, "invariant"));
     from_list->_tail->set_next(_head);
   } else {
-    assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant"));
+    assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant"));
     _tail = from_list->_tail;
   }
   _head = from_list->_head;
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -62,8 +62,6 @@
   friend class VMStructs;
 
 protected:
-  static uint calculate_region_num(HeapRegion* hr);
-
   static uint _unrealistically_long_length;
 
   // The number of regions added to the set. If the set contains
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -33,11 +33,7 @@
   // Assumes the caller has already verified the region.
 
   _length           += 1;
-  if (!hr->isHumongous()) {
-    _region_num     += 1;
-  } else {
-    _region_num     += calculate_region_num(hr);
-  }
+  _region_num       += hr->region_num();
   _total_used_bytes += hr->used();
 }
 
@@ -54,12 +50,7 @@
   assert(_length > 0, hrs_ext_msg(this, "pre-condition"));
   _length -= 1;
 
-  uint region_num_diff;
-  if (!hr->isHumongous()) {
-    region_num_diff = 1;
-  } else {
-    region_num_diff = calculate_region_num(hr);
-  }
+  uint region_num_diff = hr->region_num();
   assert(region_num_diff <= _region_num,
          hrs_err_msg("[%s] region's region num: %u "
                      "should be <= region num: %u",
--- a/hotspot/src/share/vm/utilities/decoder.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/utilities/decoder.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -91,6 +91,18 @@
   return decoder->decode(addr, buf, buflen, offset, modulepath);
 }
 
+bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const void* base) {
+  assert(_shared_decoder_lock != NULL, "Just check");
+  bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+  MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
+  AbstractDecoder* decoder = error_handling_thread ?
+    get_error_handler_instance(): get_shared_instance();
+  assert(decoder != NULL, "null decoder");
+
+  return decoder->decode(addr, buf, buflen, offset, base);
+}
+
+
 bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
   assert(_shared_decoder_lock != NULL, "Just check");
   bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
--- a/hotspot/src/share/vm/utilities/decoder.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/utilities/decoder.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -47,6 +47,8 @@
   // the function
   virtual bool decode(address pc, char* buf, int buflen, int* offset,
     const char* modulepath = NULL) = 0;
+  virtual bool decode(address pc, char* buf, int buflen, int* offset, const void* base) = 0;
+
   // demangle a C++ symbol
   virtual bool demangle(const char* symbol, char* buf, int buflen) = 0;
   // if the decoder can decode symbols in vm
@@ -82,6 +84,10 @@
     return false;
   }
 
+  virtual bool decode(address pc, char* buf, int buflen, int* offset, const void* base) {
+    return false;
+  }
+
   virtual bool demangle(const char* symbol, char* buf, int buflen) {
     return false;
   }
@@ -95,6 +101,7 @@
 class Decoder : AllStatic {
 public:
   static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL);
+  static bool decode(address pc, char* buf, int buflen, int* offset, const void* base);
   static bool demangle(const char* symbol, char* buf, int buflen);
   static bool can_decode_C_frame_in_vm();
 
--- a/hotspot/src/share/vm/utilities/decoder_elf.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/utilities/decoder_elf.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -43,6 +43,10 @@
 
   bool demangle(const char* symbol, char *buf, int buflen);
   bool decode(address addr, char *buf, int buflen, int* offset, const char* filepath = NULL);
+  bool decode(address addr, char *buf, int buflen, int* offset, const void *base) {
+    ShouldNotReachHere();
+    return false;
+  }
 
 private:
   ElfFile*         get_elf_file(const char* filepath);
--- a/hotspot/src/share/vm/utilities/hashtable.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -135,7 +135,7 @@
       // walking the hashtable past these entries requires
       // BasicHashtableEntry::make_ptr() call.
       bool keep_shared = p->is_shared();
-      unlink_entry(p);
+      this->unlink_entry(p);
       new_table->add_entry(index, p);
       if (keep_shared) {
         p->set_shared();
--- a/hotspot/src/share/vm/utilities/hashtable.hpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/hotspot/src/share/vm/utilities/hashtable.hpp	Tue Aug 07 20:23:41 2012 -0700
@@ -260,7 +260,7 @@
   }
 
   int index_for(Symbol* name) {
-    return hash_to_index(compute_hash(name));
+    return this->hash_to_index(compute_hash(name));
   }
 
   // Table entry management
--- a/jaxp/.hgtags	Tue Aug 07 12:47:45 2012 +0100
+++ b/jaxp/.hgtags	Tue Aug 07 20:23:41 2012 -0700
@@ -171,3 +171,4 @@
 404521944ac9383afda7d55d60713b212c730646 jdk8-b47
 1c88da9a1365797e49be77ae42c34bbc0a3c3f0c jdk8-b48
 f81e981eca7b63316cf9d778f93903a4fc62161d jdk8-b49
+2791ec55f66b57a702349c649567a391e6301f4e jdk8-b50
--- a/jaxws/.hgtags	Tue Aug 07 12:47:45 2012 +0100
+++ b/jaxws/.hgtags	Tue Aug 07 20:23:41 2012 -0700
@@ -171,3 +171,4 @@
 fe6a060afc404dcf0921708a740de770666b781f jdk8-b47
 efb564de8a8ee397a65fab77d45cb20200f6ddd8 jdk8-b48
 b48865af8ac559ba6f60fb86fa3fe0ebdd22746c jdk8-b49
+bdab72e87b83bcccf3abe6eaaa4cdc7b1cd2d92b jdk8-b50
--- a/jdk/.hgtags	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/.hgtags	Tue Aug 07 20:23:41 2012 -0700
@@ -171,3 +171,4 @@
 00b22b23269a57d0bb46c57753be2fe9a9d2c1a3 jdk8-b47
 3e4ab821f46166fcf63e8fe5c8046216003c941f jdk8-b48
 51707c3b75c0f521794d9ab425f4e5b2351c70c1 jdk8-b49
+e4bae5c53fca8fcb9393d47fd36a34b9e2e8d4ec jdk8-b50
--- a/jdk/make/Makefile	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/make/Makefile	Tue Aug 07 20:23:41 2012 -0700
@@ -237,7 +237,7 @@
   SUBDIRS += apple
 endif
 SUBDIRS_tools = launchers
-SUBDIRS_misc  = org sunw jpda
+SUBDIRS_misc  = org jpda
 
 # demos
 ifndef NO_DEMOS
--- a/jdk/make/common/Release.gmk	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/make/common/Release.gmk	Tue Aug 07 20:23:41 2012 -0700
@@ -305,8 +305,7 @@
 	org/ietf			\
 	org/omg				\
 	org/w3c/dom			\
-	org/xml/sax			\
-	sunw
+	org/xml/sax
 #
 # Directories where sources may be found.  If a file with the same path
 # name exists in more than one of these places, the one found last on this
--- a/jdk/make/docs/CORE_PKGS.gmk	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/make/docs/CORE_PKGS.gmk	Tue Aug 07 20:23:41 2012 -0700
@@ -33,7 +33,6 @@
   java.awt.peer            \
   java.awt.dnd.peer        \
   sun.*                    \
-  sunw.*                   \
   com.sun.*                \
   org.apache.*             \
   org.jcp.*		   \
--- a/jdk/make/sunw/Makefile	Tue Aug 07 12:47:45 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#
-# Copyright (c) 1996, 2005, 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.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# 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.
-#
-
-BUILDDIR = ..
-PACKAGE = sunw
-PRODUCT = sun
-include $(BUILDDIR)/common/Defs.gmk
-
-#
-# Files
-#
-FILES_java = \
-	sunw/util/EventObject.java \
-        sunw/util/EventListener.java \
-        sunw/io/Serializable.java
-
-#
-# include rules
-#
-include $(BUILDDIR)/common/Rules.gmk
-
-#
-# Rules
-#
-clean clobber:: .delete.classlist
-	$(RM) -r $(CLASSBINDIR)/sunw
-
--- a/jdk/makefiles/CreateJars.gmk	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/makefiles/CreateJars.gmk	Tue Aug 07 20:23:41 2012 -0700
@@ -807,8 +807,7 @@
 	org/ietf			\
 	org/omg				\
 	org/w3c/dom			\
-	org/xml/sax			\
-	sunw
+	org/xml/sax
 
 SRC_ZIP_SRCS = $(JDK_TOPDIR)/src/share/classes $(JDK_TOPDIR)/src/$(LEGACY_OPENJDK_TARGET_OS_API)/classes
 SRC_ZIP_SRCS += $(JDK_OUTPUTDIR)/gensrc
--- a/jdk/makefiles/docs/CORE_PKGS.gmk	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/makefiles/docs/CORE_PKGS.gmk	Tue Aug 07 20:23:41 2012 -0700
@@ -33,7 +33,6 @@
   java.awt.peer            \
   java.awt.dnd.peer        \
   sun.*                    \
-  sunw.*                   \
   com.sun.*                \
   org.apache.*             \
   org.jcp.*		   \
--- a/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java	Tue Aug 07 20:23:41 2012 -0700
@@ -259,7 +259,8 @@
     protected void installKeyboardActions() {
         super.installKeyboardActions();
 
-        final ActionMap actionMap = comboBox.getActionMap();
+        ActionMap actionMap = new ActionMapUIResource();
+
         actionMap.put("aquaSelectNext", highlightNextAction);
         actionMap.put("aquaSelectPrevious", highlightPreviousAction);
         actionMap.put("aquaEnterPressed", triggerSelectionAction);
@@ -269,6 +270,8 @@
         actionMap.put("aquaSelectEnd", highlightLastAction);
         actionMap.put("aquaSelectPageUp", highlightPageUpAction);
         actionMap.put("aquaSelectPageDown", highlightPageDownAction);
+
+        SwingUtilities.replaceUIActionMap(comboBox, actionMap);
     }
 
     abstract class ComboBoxAction extends AbstractAction {
--- a/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java	Tue Aug 07 20:23:41 2012 -0700
@@ -129,16 +129,6 @@
     }
 
     @Override
-    public void setText(final String l) {
-        // Please note that we do not want to post an event
-        // if TextArea.setText() replaces an empty text by an empty text,
-        // that is, if component's text remains unchanged.
-        if (!l.isEmpty() || getTextComponent().getDocument().getLength() != 0) {
-            super.setText(l);
-        }
-    }
-
-    @Override
     public void replaceRange(final String text, final int start,
                              final int end) {
         synchronized (getDelegateLock()) {
--- a/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java	Tue Aug 07 20:23:41 2012 -0700
@@ -124,7 +124,7 @@
     }
 
     @Override
-    public void setText(final String l) {
+    public final void setText(final String l) {
         synchronized (getDelegateLock()) {
             // JTextArea.setText() posts two different events (remove & insert).
             // Since we make no differences between text events,
--- a/jdk/src/share/classes/com/sun/beans/TypeResolver.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/share/classes/com/sun/beans/TypeResolver.java	Tue Aug 07 20:23:41 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -45,6 +45,9 @@
  * @author Sergey Malenkov
  */
 public final class TypeResolver {
+
+    private static final WeakCache<Type, Map<Type, Type>> CACHE = new WeakCache<>();
+
     /**
      * Replaces the given {@code type} in an inherited method
      * with the actual type it has in the given {@code inClass}.
@@ -149,12 +152,55 @@
      * @param formal  the type where occurrences of the variables
      *                in {@code actual} will be replaced by the corresponding bound values
      * @return a resolved type
-     *
-     * @see #TypeResolver(Type)
-     * @see #resolve(Type)
      */
     public static Type resolve(Type actual, Type formal) {
-        return getTypeResolver(actual).resolve(formal);
+        if (formal instanceof Class) {
+            return formal;
+        }
+        if (formal instanceof GenericArrayType) {
+            Type comp = ((GenericArrayType) formal).getGenericComponentType();
+            comp = resolve(actual, comp);
+            return (comp instanceof Class)
+                    ? Array.newInstance((Class<?>) comp, 0).getClass()
+                    : GenericArrayTypeImpl.make(comp);
+        }
+        if (formal instanceof ParameterizedType) {
+            ParameterizedType fpt = (ParameterizedType) formal;
+            Type[] actuals = resolve(actual, fpt.getActualTypeArguments());
+            return ParameterizedTypeImpl.make(
+                    (Class<?>) fpt.getRawType(), actuals, fpt.getOwnerType());
+        }
+        if (formal instanceof WildcardType) {
+            WildcardType fwt = (WildcardType) formal;
+            Type[] upper = resolve(actual, fwt.getUpperBounds());
+            Type[] lower = resolve(actual, fwt.getLowerBounds());
+            return new WildcardTypeImpl(upper, lower);
+        }
+        if (formal instanceof TypeVariable) {
+            Map<Type, Type> map;
+            synchronized (CACHE) {
+                map = CACHE.get(actual);
+                if (map == null) {
+                    map = new HashMap<>();
+                    prepare(map, actual);
+                    CACHE.put(actual, map);
+                }
+            }
+            Type result = map.get(formal);
+            if (result == null || result.equals(formal)) {
+                return formal;
+            }
+            result = fixGenericArray(result);
+            // A variable can be bound to another variable that is itself bound
+            // to something.  For example, given:
+            // class Super<T> {...}
+            // class Mid<X> extends Super<T> {...}
+            // class Sub extends Mid<String>
+            // the variable T is bound to X, which is in turn bound to String.
+            // So if we have to resolve T, we need the tail recursion here.
+            return resolve(actual, result);
+        }
+        throw new IllegalArgumentException("Bad Type kind: " + formal.getClass());
     }
 
     /**
@@ -164,12 +210,14 @@
      * @param actual   the type that supplies bindings for type variables
      * @param formals  the array of types to resolve
      * @return an array of resolved types
-     *
-     * @see #TypeResolver(Type)
-     * @see #resolve(Type[])
      */
     public static Type[] resolve(Type actual, Type[] formals) {
-        return getTypeResolver(actual).resolve(formals);
+        int length = formals.length;
+        Type[] actuals = new Type[length];
+        for (int i = 0; i < length; i++) {
+            actuals[i] = resolve(actual, formals[i]);
+        }
+        return actuals;
     }
 
     /**
@@ -228,32 +276,6 @@
         return classes;
     }
 
-    public static TypeResolver getTypeResolver(Type type) {
-        synchronized (CACHE) {
-            TypeResolver resolver = CACHE.get(type);
-            if (resolver == null) {
-                resolver = new TypeResolver(type);
-                CACHE.put(type, resolver);
-            }
-            return resolver;
-        }
-    }
-
-    private static final WeakCache<Type, TypeResolver> CACHE = new WeakCache<>();
-
-    private final Map<TypeVariable<?>, Type> map = new HashMap<>();
-
-    /**
-     * Constructs the type resolver for the given actual type.
-     *
-     * @param actual  the type that supplies bindings for type variables
-     *
-     * @see #prepare(Type)
-     */
-    private TypeResolver(Type actual) {
-        prepare(actual);
-    }
-
     /**
      * Fills the map from type parameters
      * to types as seen by the given {@code type}.
@@ -265,9 +287,10 @@
      * to a {@link ParameterizedType ParameterizedType} with no parameters,
      * or it represents the erasure of a {@link ParameterizedType ParameterizedType}.
      *
+     * @param map   the mappings of all type variables
      * @param type  the next type in the hierarchy
      */
-    private void prepare(Type type) {
+    private static void prepare(Map<Type, Type> map, Type type) {
         Class<?> raw = (Class<?>)((type instanceof Class<?>)
                 ? type
                 : ((ParameterizedType)type).getRawType());
@@ -280,91 +303,25 @@
 
         assert formals.length == actuals.length;
         for (int i = 0; i < formals.length; i++) {
-            this.map.put(formals[i], actuals[i]);
+            map.put(formals[i], actuals[i]);
         }
         Type gSuperclass = raw.getGenericSuperclass();
         if (gSuperclass != null) {
-            prepare(gSuperclass);
+            prepare(map, gSuperclass);
         }
         for (Type gInterface : raw.getGenericInterfaces()) {
-            prepare(gInterface);
+            prepare(map, gInterface);
         }
         // If type is the raw version of a parameterized class, we type-erase
         // all of its type variables, including inherited ones.
         if (type instanceof Class<?> && formals.length > 0) {
-            for (Map.Entry<TypeVariable<?>, Type> entry : this.map.entrySet()) {
+            for (Map.Entry<Type, Type> entry : map.entrySet()) {
                 entry.setValue(erase(entry.getValue()));
             }
         }
     }
 
     /**
-     * Replaces the given {@code formal} type
-     * with the type it stand for in this type resolver.
-     *
-     * @param formal  the array of types to resolve
-     * @return a resolved type
-     */
-    private Type resolve(Type formal) {
-        if (formal instanceof Class) {
-            return formal;
-        }
-        if (formal instanceof GenericArrayType) {
-            Type comp = ((GenericArrayType)formal).getGenericComponentType();
-            comp = resolve(comp);
-            return (comp instanceof Class)
-                    ? Array.newInstance((Class<?>)comp, 0).getClass()
-                    : GenericArrayTypeImpl.make(comp);
-        }
-        if (formal instanceof ParameterizedType) {
-            ParameterizedType fpt = (ParameterizedType)formal;
-            Type[] actuals = resolve(fpt.getActualTypeArguments());
-            return ParameterizedTypeImpl.make(
-                    (Class<?>)fpt.getRawType(), actuals, fpt.getOwnerType());
-        }
-        if (formal instanceof WildcardType) {
-            WildcardType fwt = (WildcardType)formal;
-            Type[] upper = resolve(fwt.getUpperBounds());
-            Type[] lower = resolve(fwt.getLowerBounds());
-            return new WildcardTypeImpl(upper, lower);
-        }
-        if (!(formal instanceof TypeVariable)) {
-            throw new IllegalArgumentException("Bad Type kind: " + formal.getClass());
-        }
-        Type actual = this.map.get((TypeVariable) formal);
-        if (actual == null || actual.equals(formal)) {
-            return formal;
-        }
-        actual = fixGenericArray(actual);
-        return resolve(actual);
-        // A variable can be bound to another variable that is itself bound
-        // to something.  For example, given:
-        // class Super<T> {...}
-        // class Mid<X> extends Super<T> {...}
-        // class Sub extends Mid<String>
-        // the variable T is bound to X, which is in turn bound to String.
-        // So if we have to resolve T, we need the tail recursion here.
-    }
-
-    /**
-     * Replaces all formal types in the given array
-     * with the types they stand for in this type resolver.
-     *
-     * @param formals  the array of types to resolve
-     * @return an array of resolved types
-     *
-     * @see #resolve(Type)
-     */
-    private Type[] resolve(Type[] formals) {
-        int length = formals.length;
-        Type[] actuals = new Type[length];
-        for (int i = 0; i < length; i++) {
-            actuals[i] = resolve(formals[i]);
-        }
-        return actuals;
-    }
-
-    /**
      * Replaces a {@link GenericArrayType GenericArrayType}
      * with plain array class where it is possible.
      * Bug <a href="http://bugs.sun.com/view_bug.do?bug_id=5041784">5041784</a>
--- a/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java	Tue Aug 07 20:23:41 2012 -0700
@@ -164,8 +164,10 @@
                             return findAccessibleMethod(m);
                         }
                         Type[] gpts = m.getGenericParameterTypes();
-                        if (Arrays.equals(params, TypeResolver.erase(TypeResolver.resolve(pt, gpts)))) {
-                            return findAccessibleMethod(m);
+                        if (params.length == gpts.length) {
+                            if (Arrays.equals(params, TypeResolver.erase(TypeResolver.resolve(pt, gpts)))) {
+                                return findAccessibleMethod(m);
+                            }
                         }
                     }
                 }
--- a/jdk/src/share/classes/java/awt/GraphicsEnvironment.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/share/classes/java/awt/GraphicsEnvironment.java	Tue Aug 07 20:23:41 2012 -0700
@@ -170,12 +170,12 @@
                         if (System.getProperty("javaplugin.version") != null) {
                             headless = defaultHeadless = Boolean.FALSE;
                         } else {
-                            if ("sun.awt.HeadlessGraphicsEnvironment".equals(
-                                    System.getProperty("java.awt.graphicsenv")))
+                            String osName = System.getProperty("os.name");
+                            if (osName.contains("OS X") && "sun.awt.HToolkit".equals(
+                                    System.getProperty("awt.toolkit")))
                             {
                                 headless = defaultHeadless = Boolean.TRUE;
                             } else {
-                                String osName = System.getProperty("os.name");
                                 headless = defaultHeadless =
                                     Boolean.valueOf(("Linux".equals(osName) ||
                                                      "SunOS".equals(osName) ||
--- a/jdk/src/share/classes/java/awt/TextComponent.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/share/classes/java/awt/TextComponent.java	Tue Aug 07 20:23:41 2012 -0700
@@ -235,9 +235,14 @@
      * @see         java.awt.TextComponent#getText
      */
     public synchronized void setText(String t) {
+        boolean skipTextEvent = (text == null || text.isEmpty())
+                && (t == null || t.isEmpty());
         text = (t != null) ? t : "";
         TextComponentPeer peer = (TextComponentPeer)this.peer;
-        if (peer != null) {
+        // Please note that we do not want to post an event
+        // if TextArea.setText() or TextField.setText() replaces an empty text
+        // by an empty text, that is, if component's text remains unchanged.
+        if (peer != null && !skipTextEvent) {
             peer.setText(text);
         }
     }
--- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Tue Aug 07 20:23:41 2012 -0700
@@ -181,20 +181,21 @@
                 // the Indexed readMethod was explicitly set to null.
                 return null;
             }
+            String nextMethodName = Introspector.GET_PREFIX + getBaseName();
             if (indexedReadMethodName == null) {
                 Class<?> type = getIndexedPropertyType0();
                 if (type == boolean.class || type == null) {
                     indexedReadMethodName = Introspector.IS_PREFIX + getBaseName();
                 } else {
-                    indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
+                    indexedReadMethodName = nextMethodName;
                 }
             }
 
             Class<?>[] args = { int.class };
             indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
-            if (indexedReadMethod == null) {
+            if ((indexedReadMethod == null) && !indexedReadMethodName.equals(nextMethodName)) {
                 // no "is" method, so look for a "get" method.
-                indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
+                indexedReadMethodName = nextMethodName;
                 indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
             }
             setIndexedReadMethod0(indexedReadMethod);
--- a/jdk/src/share/classes/java/beans/Introspector.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/share/classes/java/beans/Introspector.java	Tue Aug 07 20:23:41 2012 -0700
@@ -25,6 +25,7 @@
 
 package java.beans;
 
+import com.sun.beans.TypeResolver;
 import com.sun.beans.WeakCache;
 import com.sun.beans.finder.ClassFinder;
 
@@ -34,6 +35,7 @@
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
 
 import java.util.Map;
 import java.util.ArrayList;
@@ -951,44 +953,61 @@
                     continue;
                 }
 
-                Class<?>[] argTypes = FeatureDescriptor.getParameterTypes(beanClass, method);
-                Class<?> resultType = FeatureDescriptor.getReturnType(beanClass, method);
-
-                if (name.startsWith(ADD_PREFIX) && argTypes.length == 1 &&
-                    resultType == Void.TYPE &&
-                    Introspector.isSubclass(argTypes[0], eventListenerType)) {
-                    String listenerName = name.substring(3);
-                    if (listenerName.length() > 0 &&
-                        argTypes[0].getName().endsWith(listenerName)) {
-                        if (adds == null) {
-                            adds = new HashMap<>();
+                if (name.startsWith(ADD_PREFIX)) {
+                    Class<?> returnType = method.getReturnType();
+                    if (returnType == void.class) {
+                        Type[] parameterTypes = method.getGenericParameterTypes();
+                        if (parameterTypes.length == 1) {
+                            Class<?> type = TypeResolver.erase(TypeResolver.resolveInClass(beanClass, parameterTypes[0]));
+                            if (Introspector.isSubclass(type, eventListenerType)) {
+                                String listenerName = name.substring(3);
+                                if (listenerName.length() > 0 &&
+                                    type.getName().endsWith(listenerName)) {
+                                    if (adds == null) {
+                                        adds = new HashMap<>();
+                                    }
+                                    adds.put(listenerName, method);
+                                }
+                            }
                         }
-                        adds.put(listenerName, method);
                     }
                 }
-                else if (name.startsWith(REMOVE_PREFIX) && argTypes.length == 1 &&
-                         resultType == Void.TYPE &&
-                         Introspector.isSubclass(argTypes[0], eventListenerType)) {
-                    String listenerName = name.substring(6);
-                    if (listenerName.length() > 0 &&
-                        argTypes[0].getName().endsWith(listenerName)) {
-                        if (removes == null) {
-                            removes = new HashMap<>();
+                else if (name.startsWith(REMOVE_PREFIX)) {
+                    Class<?> returnType = method.getReturnType();
+                    if (returnType == void.class) {
+                        Type[] parameterTypes = method.getGenericParameterTypes();
+                        if (parameterTypes.length == 1) {
+                            Class<?> type = TypeResolver.erase(TypeResolver.resolveInClass(beanClass, parameterTypes[0]));
+                            if (Introspector.isSubclass(type, eventListenerType)) {
+                                String listenerName = name.substring(6);
+                                if (listenerName.length() > 0 &&
+                                    type.getName().endsWith(listenerName)) {
+                                    if (removes == null) {
+                                        removes = new HashMap<>();
+                                    }
+                                    removes.put(listenerName, method);
+                                }
+                            }
                         }
-                        removes.put(listenerName, method);
                     }
                 }
-                else if (name.startsWith(GET_PREFIX) && argTypes.length == 0 &&
-                         resultType.isArray() &&
-                         Introspector.isSubclass(resultType.getComponentType(),
-                                                 eventListenerType)) {
-                    String listenerName  = name.substring(3, name.length() - 1);
-                    if (listenerName.length() > 0 &&
-                        resultType.getComponentType().getName().endsWith(listenerName)) {
-                        if (gets == null) {
-                            gets = new HashMap<>();
+                else if (name.startsWith(GET_PREFIX)) {
+                    Class<?>[] parameterTypes = method.getParameterTypes();
+                    if (parameterTypes.length == 0) {
+                        Class<?> returnType = FeatureDescriptor.getReturnType(beanClass, method);
+                        if (returnType.isArray()) {
+                            Class<?> type = returnType.getComponentType();
+                            if (Introspector.isSubclass(type, eventListenerType)) {
+                                String listenerName  = name.substring(3, name.length() - 1);
+                                if (listenerName.length() > 0 &&
+                                    type.getName().endsWith(listenerName)) {
+                                    if (gets == null) {
+                                        gets = new HashMap<>();
+                                    }
+                                    gets.put(listenerName, method);
+                                }
+                            }
                         }
-                        gets.put(listenerName, method);
                     }
                 }
             }
@@ -1240,11 +1259,11 @@
     private boolean isEventHandler(Method m) {
         // We assume that a method is an event handler if it has a single
         // argument, whose type inherit from java.util.Event.
-        Class argTypes[] = FeatureDescriptor.getParameterTypes(beanClass, m);
+        Type argTypes[] = m.getGenericParameterTypes();
         if (argTypes.length != 1) {
             return false;
         }
-        return isSubclass(argTypes[0], EventObject.class);
+        return isSubclass(TypeResolver.erase(TypeResolver.resolveInClass(beanClass, argTypes[0])), EventObject.class);
     }
 
     /*
@@ -1296,24 +1315,25 @@
                 }
 
                 // make sure method signature matches.
-                Class params[] = FeatureDescriptor.getParameterTypes(start, method);
-                if (method.getName().equals(methodName) &&
-                    params.length == argCount) {
-                    if (args != null) {
-                        boolean different = false;
-                        if (argCount > 0) {
-                            for (int j = 0; j < argCount; j++) {
-                                if (params[j] != args[j]) {
-                                    different = true;
+                if (method.getName().equals(methodName)) {
+                    Type[] params = method.getGenericParameterTypes();
+                    if (params.length == argCount) {
+                        if (args != null) {
+                            boolean different = false;
+                            if (argCount > 0) {
+                                for (int j = 0; j < argCount; j++) {
+                                    if (TypeResolver.erase(TypeResolver.resolveInClass(start, params[j])) != args[j]) {
+                                        different = true;
+                                        continue;
+                                    }
+                                }
+                                if (different) {
                                     continue;
                                 }
                             }
-                            if (different) {
-                                continue;
-                            }
                         }
+                        return method;
                     }
-                    return method;
                 }
             }
         }
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Tue Aug 07 20:23:41 2012 -0700
@@ -210,12 +210,13 @@
                 // The read method was explicitly set to null.
                 return null;
             }
+            String nextMethodName = Introspector.GET_PREFIX + getBaseName();
             if (readMethodName == null) {
                 Class<?> type = getPropertyType0();
                 if (type == boolean.class || type == null) {
                     readMethodName = Introspector.IS_PREFIX + getBaseName();
                 } else {
-                    readMethodName = Introspector.GET_PREFIX + getBaseName();
+                    readMethodName = nextMethodName;
                 }
             }
 
@@ -225,8 +226,8 @@
             // methods.  If an "is" method exists, this is the official
             // reader method so look for this one first.
             readMethod = Introspector.findMethod(cls, readMethodName, 0);
-            if (readMethod == null) {
-                readMethodName = Introspector.GET_PREFIX + getBaseName();
+            if ((readMethod == null) && !readMethodName.equals(nextMethodName)) {
+                readMethodName = nextMethodName;
                 readMethod = Introspector.findMethod(cls, readMethodName, 0);
             }
             try {
--- a/jdk/src/share/classes/javax/swing/TimerQueue.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/share/classes/javax/swing/TimerQueue.java	Tue Aug 07 20:23:41 2012 -0700
@@ -187,6 +187,9 @@
                                 addTimer(delayedTimer);
                             }
                         }
+
+                        // Allow run other threads on systems without kernel threads
+                        timer.getLock().newCondition().awaitNanos(1);
                     } catch (SecurityException ignore) {
                     } finally {
                         timer.getLock().unlock();
--- a/jdk/src/share/classes/sun/misc/MetaIndex.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/share/classes/sun/misc/MetaIndex.java	Tue Aug 07 20:23:41 2012 -0700
@@ -71,7 +71,6 @@
 org/w3c/
 com/sun/imageio/
 javax/
-sunw/util/
 java/
 sun/
 ...
--- a/jdk/src/share/classes/sunw/io/Serializable.java	Tue Aug 07 12:47:45 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1996, 1997, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sunw.io;
-
-/**
- * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
- * <p>
- * This is a backwards compatibility class to allow Java Beans that
- * were developed under JDK 1.0.2 to run correctly under JDK 1.1
- * <p>
- * To allow beans development under JDK 1.0.2, JavaSoft delivered three
- * no-op interfaces/classes (sunw.io.Serializable, sunw.util.EventObject
- * and sunw.util.EventListener) that could be downloaded into JDK 1.0.2
- * systems and which would act as placeholders for the real JDK 1.1
- * classes.
- * <p>
- * Now under JDK 1.1 we provide versions of these classes and interfaces
- * that inherit from the real version in java.util and java.io.  These
- * mean that beans developed under JDK 1.0.2 against the sunw.* classes
- * will now continue to work on JDK 1.1 and will (indirectly) inherit
- * from the appropriate java.* interfaces/classes.
- *
- * @deprecated This is a compatibility type to allow Java Beans that
- * were developed under JDK 1.0.2 to run correctly under JDK 1.1.  The
- * corresponding JDK1.1 type is java.io.Serializable
- *
- * @see java.io.Serializable
- */
-
-public interface Serializable extends java.io.Serializable {
-}
--- a/jdk/src/share/classes/sunw/util/EventListener.java	Tue Aug 07 12:47:45 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1996, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sunw.util;
-
-/**
- * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
- * <p>
- * This is a backwards compatibility class to allow Java Beans that
- * were developed under JDK 1.0.2 to run correctly under JDK 1.1
- * <p>
- * To allow beans development under JDK 1.0.2, JavaSoft delivered three
- * no-op interfaces/classes (sunw.io.Serializable, sunw.util.EventObject
- * and sunw.util.EventListener) that could be downloaded into JDK 1.0.2
- * systems and which would act as placeholders for the real JDK 1.1
- * classes.
- * <p>
- * Now under JDK 1.1 we provide versions of these classes and interfaces
- * that inherit from the real version in java.util and java.io.  These
- * mean that beans developed under JDK 1.0.2 against the sunw.* classes
- * will now continue to work on JDK 1.1 and will (indirectly) inherit
- * from the approrpiate java.* interfaces/classes.
- *
- * @deprecated This is a compatibility type to allow Java Beans that
- * were developed under JDK 1.0.2 to run correctly under JDK 1.1.  The
- * corresponding JDK1.1 type is java.util.EventListener
- *
- * @see java.util.EventListener
- */
-
-public interface EventListener extends java.util.EventListener {
-}
--- a/jdk/src/share/classes/sunw/util/EventObject.java	Tue Aug 07 12:47:45 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 1996, 2003, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sunw.util;
-
-/**
- * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
- * <p>
- * This is a backwards compatibility class to allow Java Beans that
- * were developed under JDK 1.0.2 to run correctly under JDK 1.1
- * <p>
- * To allow beans development under JDK 1.0.2, JavaSoft delivered three
- * no-op interfaces/classes (sunw.io.Serializable, sunw.util.EventObject
- * and sunw.util.EventListener) that could be downloaded into JDK 1.0.2
- * systems and which would act as placeholders for the real JDK 1.1
- * classes.
- * <p>
- * Now under JDK 1.1 we provide versions of these classes and interfaces
- * that inherit from the real version in java.util and java.io.  These
- * mean that beans developed under JDK 1.0.2 against the sunw.* classes
- * will now continue to work on JDK 1.1 and will (indirectly) inherit
- * from the approrpiate java.* interfaces/classes.
- *
- * @deprecated This is a compatibility type to allow Java Beans that
- * were developed under JDK 1.0.2 to run correctly under JDK 1.1.  The
- * corresponding JDK1.1 type is java.util.EventObject
- *
- * @see java.util.EventObject
- */
-
-public class EventObject extends java.util.EventObject {
-
-    private static final long serialVersionUID = 6723767567830330255L;
-
-    public EventObject(Object source) {
-        super(source);
-    }
-
-}
--- a/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java	Tue Aug 07 20:23:41 2012 -0700
@@ -463,13 +463,6 @@
 
     protected boolean setTextImpl(String txt) {
         if (jtext != null) {
-            // Please note that we do not want to post an event
-            // if setText() replaces an empty text by an empty text,
-            // that is, if component's text remains unchanged.
-            if (jtext.getDocument().getLength() == 0 && txt.length() == 0) {
-                return true;
-            }
-
             // JTextArea.setText() posts two different events (remove & insert).
             // Since we make no differences between text events,
             // the document listener has to be disabled while
--- a/jdk/src/solaris/native/java/lang/java_props_md.c	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/solaris/native/java/lang/java_props_md.c	Tue Aug 07 20:23:41 2012 -0700
@@ -431,6 +431,7 @@
     PreferredToolkit prefToolkit = getPreferredToolkit();
     switch (prefToolkit) {
         case CToolkit:
+        case HToolkit:
             sprops.graphics_env = "sun.awt.CGraphicsEnvironment";
             break;
         case XToolkit:
@@ -438,9 +439,6 @@
     sprops.graphics_env = "sun.awt.X11GraphicsEnvironment";
 #ifdef MACOSX
             break;
-        default:
-            sprops.graphics_env = "sun.java2d.HeadlessGraphicsEnvironment";
-            break;
     }
 #endif
     /* AWT properties */
--- a/jdk/src/windows/native/sun/windows/awt_TextArea.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/windows/native/sun/windows/awt_TextArea.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -131,48 +131,13 @@
     MsgRouting mr = mrDoDefault;
 
     switch (message) {
-        case WM_PRINTCLIENT:
-          {
-            FORMATRANGE fr;
-            HDC hPrinterDC = (HDC)wParam;
-            int nHorizRes = ::GetDeviceCaps(hPrinterDC, HORZRES);
-            int nVertRes = ::GetDeviceCaps(hPrinterDC, VERTRES);
-            int nLogPixelsX = ::GetDeviceCaps(hPrinterDC, LOGPIXELSX);
-            int nLogPixelsY = ::GetDeviceCaps(hPrinterDC, LOGPIXELSY);
-
-            // Ensure the printer DC is in MM_TEXT mode.
-            ::SetMapMode ( hPrinterDC, MM_TEXT );
-
-            // Rendering to the same DC we are measuring.
-            ::ZeroMemory(&fr, sizeof(fr));
-            fr.hdc = fr.hdcTarget = hPrinterDC;
-            // Set up the page.
-            fr.rcPage.left     = fr.rcPage.top = 0;
-            fr.rcPage.right    = (nHorizRes/nLogPixelsX) * 1440; // in twips
-            fr.rcPage.bottom   = (nVertRes/nLogPixelsY) * 1440;
-            fr.rc.left   = fr.rcPage.left;
-            fr.rc.top    = fr.rcPage.top;
-            fr.rc.right  = fr.rcPage.right;
-            fr.rc.bottom = fr.rcPage.bottom;
-
-            // start printing from the first visible line
-            LRESULT nLine = SendMessage(EM_GETFIRSTVISIBLELINE, 0, 0);
-            LONG startCh = static_cast<LONG>(SendMessage(EM_LINEINDEX,
-                                                         (WPARAM)nLine, 0));
-            fr.chrg.cpMin = startCh;
-            fr.chrg.cpMax = -1;
-
-            SendMessage(EM_FORMATRANGE, TRUE, (LPARAM)&fr);
-          }
-
-        break;
     case EM_SETCHARFORMAT:
     case WM_SETFONT:
         SetIgnoreEnChange(TRUE);
         break;
     }
 
-    retValue = AwtComponent::WindowProc(message, wParam, lParam);
+    retValue = AwtTextComponent::WindowProc(message, wParam, lParam);
 
     switch (message) {
     case EM_SETCHARFORMAT:
--- a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp	Tue Aug 07 20:23:41 2012 -0700
@@ -215,6 +215,50 @@
     return c;
 }
 
+LRESULT
+AwtTextComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
+
+    switch (message) {
+        case WM_PRINTCLIENT:
+          {
+            FORMATRANGE fr;
+            HDC hPrinterDC = (HDC)wParam;
+            int nHorizRes = ::GetDeviceCaps(hPrinterDC, HORZRES);
+            int nVertRes = ::GetDeviceCaps(hPrinterDC, VERTRES);
+            int nLogPixelsX = ::GetDeviceCaps(hPrinterDC, LOGPIXELSX);
+            int nLogPixelsY = ::GetDeviceCaps(hPrinterDC, LOGPIXELSY);
+
+            // Ensure the printer DC is in MM_TEXT mode.
+            ::SetMapMode ( hPrinterDC, MM_TEXT );
+
+            // Rendering to the same DC we are measuring.
+            ::ZeroMemory(&fr, sizeof(fr));
+            fr.hdc = fr.hdcTarget = hPrinterDC;
+            // Set up the page.
+            fr.rcPage.left     = fr.rcPage.top = 0;
+            fr.rcPage.right    = (nHorizRes/nLogPixelsX) * 1440; // in twips
+            fr.rcPage.bottom   = (nVertRes/nLogPixelsY) * 1440;
+            fr.rc.left   = fr.rcPage.left;
+            fr.rc.top    = fr.rcPage.top;
+            fr.rc.right  = fr.rcPage.right;
+            fr.rc.bottom = fr.rcPage.bottom;
+
+            // start printing from the first visible line
+            LRESULT nLine = SendMessage(EM_GETFIRSTVISIBLELINE, 0, 0);
+            LONG startCh = static_cast<LONG>(SendMessage(EM_LINEINDEX,
+                                                         (WPARAM)nLine, 0));
+            fr.chrg.cpMin = startCh;
+            fr.chrg.cpMax = -1;
+
+            SendMessage(EM_FORMATRANGE, TRUE, (LPARAM)&fr);
+          }
+
+        break;
+    }
+
+    return AwtComponent::WindowProc(message, wParam, lParam);
+}
+
 LONG AwtTextComponent::EditGetCharFromPos(POINT& pt) {
     return static_cast<LONG>(SendMessage(EM_CHARFROMPOS, 0,
             reinterpret_cast<LPARAM>(&pt)));
--- a/jdk/src/windows/native/sun/windows/awt_TextComponent.h	Tue Aug 07 12:47:45 2012 +0100
+++ b/jdk/src/windows/native/sun/windows/awt_TextComponent.h	Tue Aug 07 20:23:41 2012 -0700
@@ -50,6 +50,7 @@
     static AwtTextComponent* Create(jobject self, jobject parent, BOOL isMultiline);
 
     virtual LPCTSTR GetClassName();
+    LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
 
     int RemoveCR(WCHAR *pStr);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/OverrideRedirectWindowActivationTest/OverrideRedirectWindowActivationTest.java	Tue Aug 07 20:23:41 2012 -0700
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2012, 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
+ * @bug       6385277
+ * @summary   Tests that override redirect window gets activated on click.
+ * @author    anton.tarasov@sun.com: area=awt.focus
+ * @library   ../../regtesthelpers
+ * @build     Util
+ * @run       main OverrideRedirectWindowActivationTest
+ */
+import java.awt.*;
+import java.awt.event.*;
+import java.util.concurrent.Callable;
+import javax.swing.SwingUtilities;
+import sun.awt.SunToolkit;
+import test.java.awt.regtesthelpers.Util;
+
+public class OverrideRedirectWindowActivationTest {
+
+    private static Frame frame;
+    private static Window window;
+    private static Button fbutton;
+    private static Button wbutton;
+    private static Label label;
+    private static Robot robot;
+    private static SunToolkit toolkit;
+
+    public static void main(String[] args) throws Exception {
+
+        if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) {
+            System.out.println("No testing on Motif. Test passed.");
+            return;
+        }
+
+        toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        robot = new Robot();
+        robot.setAutoDelay(50);
+
+        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+
+            public void eventDispatched(AWTEvent e) {
+                System.out.println(e);
+            }
+        }, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_FOCUS_EVENT_MASK);
+
+        createAndShowWindow();
+        toolkit.realSync();
+
+        createAndShowFrame();
+        toolkit.realSync();
+
+        // click on Frame
+        clickOn(getClickPoint(frame));
+
+        if (!frame.isFocused()) {
+            throw new RuntimeException("Error: a frame couldn't be focused by click.");
+        }
+
+        //click on Label in Window
+        clickOn(getClickPoint(label));
+
+        if (!window.isFocused()) {
+            throw new RuntimeException("Test failed: the window couldn't be activated by click!");
+        }
+
+        // bring focus back to the frame
+        clickOn(getClickPoint(fbutton));
+
+        if (!frame.isFocused()) {
+            throw new RuntimeException("Error: a frame couldn't be focused by click.");
+        }
+
+        // Test 2. Verifies that clicking on a component of unfocusable Window
+        //         won't activate it.
+
+        window.setFocusableWindowState(false);
+        toolkit.realSync();
+
+
+        clickOn(getClickPoint(label));
+
+        if (window.isFocused()) {
+            throw new RuntimeException("Test failed: unfocusable window got activated by click!");
+        }
+        System.out.println("Test passed.");
+
+    }
+
+    private static void createAndShowWindow() {
+
+        frame = new Frame("Test Frame");
+        window = new Window(frame);
+        wbutton = new Button("wbutton");
+        label = new Label("label");
+
+        window.setBounds(800, 200, 200, 100);
+        window.setLayout(new FlowLayout());
+        window.add(wbutton);
+        window.add(label);
+        window.setVisible(true);
+
+    }
+
+    private static void createAndShowFrame() {
+        fbutton = new Button("fbutton");
+
+        frame.setBounds(800, 0, 200, 100);
+        frame.setLayout(new FlowLayout());
+        frame.add(fbutton);
+        frame.setVisible(true);
+
+    }
+
+    static void clickOn(Point point) {
+
+        robot.mouseMove(point.x, point.y);
+
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+        toolkit.realSync();
+    }
+
+    static Point getClickPoint(Component c) {
+        Point p = c.getLocationOnScreen();
+        Dimension d = c.getSize();
+        return new Point(p.x + (int) (d.getWidth() / 2), p.y + (int) (d.getHeight() / 2));
+    }
+
+    static Point getClickPoint(Frame frame) {
+        Point p = frame.getLocationOnScreen();
+        Dimension d = frame.getSize();
+        return new Point(p.x + (int) (d.getWidth() / 2), p.y + (frame.getInsets().top / 2));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Window/Grab/GrabTest.java	Tue Aug 07 20:23:41 2012 -0700
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2012, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+  @bug 7124430
+  @summary Tests that SunToolkit.grab API works
+  @author anton.tarasov@oracle.com: area=awt.toolkit
+  @library ../../regtesthelpers
+  @build Util
+  @run main GrabTest
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class GrabTest {
+    private static Frame f;
+    private static Frame f1;
+    private static Window w;
+    private static Button b;
+
+    private static Robot robot;
+    private static sun.awt.SunToolkit tk;
+
+    static volatile boolean ungrabbed;
+    static volatile boolean buttonPressed;
+    static volatile boolean windowPressed;
+    static volatile boolean framePressed;
+
+    static volatile boolean passed = true;
+
+    public static void main(String[] args) {
+
+        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+                public void eventDispatched(AWTEvent e) {
+                    System.out.println(e);
+                    if (e instanceof sun.awt.UngrabEvent) {
+                        ungrabbed = true;
+                    }
+                }
+            }, sun.awt.SunToolkit.GRAB_EVENT_MASK);
+
+        f = new Frame("Frame");
+        f.setBounds(0, 0, 300, 300);
+        f.addMouseListener(new MouseAdapter() {
+                public void mousePressed(MouseEvent e) {
+                    System.out.println(e);
+                    framePressed = true;
+                }
+            });
+
+        f1 = new Frame("OtherFrame");
+        f1.setBounds(700, 100, 200, 200);
+
+        w = new Window(f);
+        w.setLayout(new FlowLayout());
+        b = new Button("Press");
+        b.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    System.out.println(e);
+                    buttonPressed = true;
+                }
+            });
+        w.add(b);
+        w.setBounds(400, 100, 200, 200);
+        w.setBackground(Color.blue);
+        w.addMouseListener(new MouseAdapter() {
+                public void mousePressed(MouseEvent e) {
+                    System.out.println(e);
+                    windowPressed = true;
+                }
+            });
+
+        f.setVisible(true);
+        w.setVisible(true);
+
+        tk = (sun.awt.SunToolkit)Toolkit.getDefaultToolkit();
+
+        try {
+            robot = new Robot();
+        } catch (AWTException ex) {
+            throw new RuntimeException(ex);
+        }
+
+        Util.waitForIdle(robot);
+
+        test();
+    }
+
+    public static void test() {
+        tk.grab(w);
+
+        // 1. Check that button press doesn't cause ungrab
+        Util.clickOnComp(b, robot);
+        Util.waitForIdle(robot);
+        checkAndThrow(buttonPressed, "Error: Button can not be pressed");
+        if (ungrabbed) {
+            passed = false;
+            tk.grab(w);
+            System.err.println("Failure: [1] Press inside of Window (on Button) caused ungrab");
+        }
+
+        // 2. Check that press on the window itself doesn't cause ungrab
+        Util.clickOnComp(w, robot);
+        Util.waitForIdle(robot);
+        checkAndThrow(windowPressed, "Error: Window can't be pressed");
+        if (ungrabbed) {
+            passed = false;
+            tk.grab(w);
+            System.err.println("Failure: [2] Press inside of Window caused ungrab");
+        }
+
+        // 3. Check that press on the frame causes ungrab, event must be dispatched
+        Util.clickOnComp(f, robot);
+        Util.waitForIdle(robot);
+        checkAndThrow(framePressed, "Error: Frame can't be pressed");
+        if (!ungrabbed) {
+            passed = false;
+            System.err.println("Failure: [3] Press inside of Frame didn't cause ungrab");
+        }
+        ungrabbed = false;
+        tk.grab(w);
+
+        // 4. Check that press on the frame's title causes ungrab
+        Util.clickOnTitle(f, robot);
+        Util.waitForIdle(robot);
+        if (!ungrabbed) {
+            passed = false;
+            System.err.println("Failure: [4] Press inside of Frame's title didn't cause ungrab");
+        }
+        ungrabbed = false;
+        tk.grab(w);
+
+
+        // 5. Check that press on the other frame's title causes ungrab
+        f1.setVisible(true);
+        Util.waitForIdle(robot);
+        Util.clickOnTitle(f1, robot);
+        if (!ungrabbed) {
+            passed = false;
+            System.err.println("Failure: [5] Press inside of other Frame's title didn't cause ungrab");
+        }
+        f.requestFocus(); // restore focus
+        Util.waitForIdle(robot);
+        if (!f.hasFocus()) {
+            System.err.println("Error: Frame can't be focused");
+        }
+        ungrabbed = false;
+        tk.grab(w);
+
+
+        // 6. Check that press on the outside area causes ungrab
+        Point loc = f.getLocationOnScreen();
+        robot.mouseMove(loc.x + 100, loc.y + f.getSize().height + 1);
+        Util.waitForIdle(robot);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.delay(50);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        Util.waitForIdle(robot);
+        if (!ungrabbed) {
+            passed = false;
+            System.err.println("Failure: [6] Press on the outside area didn't cause ungrab");
+        }
+        ungrabbed = false;
+        tk.grab(w);
+
+
+        // 7. Check that disposing the window causes ungrab
+        w.dispose();
+        Util.waitForIdle(robot);
+        if (!ungrabbed) {
+            passed = false;
+            System.err.println("Failure: [7] Window disposal didn't cause ungrab");
+        }
+
+        if (passed) {
+            System.out.println("Test passed.");
+        } else {
+            throw new RuntimeException("Test failed.");
+        }
+    }
+
+    public static void checkAndThrow(boolean condition, String msg) {
+        if (!condition) {
+            throw new RuntimeException(msg);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/TextEvent/TextEventSequenceTest/TextEventSequenceTest.java	Tue Aug 07 20:23:41 2012 -0700
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2012, 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
+ * @bug 4028580
+ * @summary TextArea does not send TextEvent when setText. Does for insert
+ * @author kdm@sparc.spb.su: area= awt.TextAvent
+ * @run main TextEventSequenceTest
+ */
+import java.awt.*;
+import java.awt.event.*;
+import sun.awt.SunToolkit;
+
+public class TextEventSequenceTest {
+
+    private static Frame f;
+    private static TextField tf;
+    private static TextArea t;
+    private static int cntEmptyStrings = 0;
+    private static int cntNonEmptyStrings = 0;
+
+    public static void main(String[] args) {
+
+        test("non-empty text string");
+        test("");
+        test(null);
+    }
+
+    private static void test(String test) {
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        createAndShowGUI(test);
+        toolkit.realSync();
+
+        initCounts();
+        t.setText("Hello ");
+        toolkit.realSync();
+        t.append("World! !");
+        toolkit.realSync();
+        t.insert("from Roger Pham", 13);
+        toolkit.realSync();
+        t.replaceRange("Java Duke", 18, 28);
+        toolkit.realSync();
+        checkCounts(0, 4);
+
+        initCounts();
+        t.setText("");
+        toolkit.realSync();
+        t.setText("");
+        toolkit.realSync();
+        t.setText("");
+        toolkit.realSync();
+        checkCounts(1, 0);
+
+        initCounts();
+        tf.setText("Hello There!");
+        toolkit.realSync();
+        checkCounts(0, 1);
+
+        initCounts();
+        tf.setText("");
+        toolkit.realSync();
+        tf.setText("");
+        toolkit.realSync();
+        tf.setText("");
+        toolkit.realSync();
+        checkCounts(1, 0);
+
+        f.dispose();
+    }
+
+    private static void createAndShowGUI(String text) {
+        f = new Frame("TextEventSequenceTest");
+        f.setLayout(new FlowLayout());
+
+        TextListener listener = new MyTextListener();
+
+        tf = new TextField(text);
+        tf.addTextListener(listener);
+        f.add(tf);
+
+        t = new TextArea(text, 10, 30);
+        t.addTextListener(listener);
+        f.add(t);
+
+        f.pack();
+        f.setVisible(true);
+    }
+
+    static class MyTextListener implements TextListener {
+
+        public synchronized void textValueChanged(TextEvent e) {
+            TextComponent tc = (TextComponent) e.getSource();
+            String text = tc.getText();
+            if (text.length() == 0) {
+                cntEmptyStrings++;
+            } else {
+                cntNonEmptyStrings++;
+            }
+        }
+    }
+
+    synchronized static void initCounts() {
+        cntEmptyStrings = 0;
+        cntNonEmptyStrings = 0;
+    }
+
+    synchronized static void checkCounts(int empty, int nonempty) {
+        if (empty != cntEmptyStrings || nonempty != cntNonEmptyStrings) {
+            throw new RuntimeException(
+                    String.format("Expected events: empty = %d, nonempty = %d, "
+                    + "actual events: empty = %d, nonempty = %d",
+                    empty, nonempty, cntEmptyStrings, cntNonEmptyStrings));
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Performance/Test7122740.java	Tue Aug 07 20:23:41 2012 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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
+ * @bug 7122740
+ * @summary Tests just a benchmark of PropertyDescriptor(String, Class) performance
+ * @author Sergey Malenkov
+ * @run main/manual Test7122740
+ */
+
+import java.beans.PropertyDescriptor;
+
+public class Test7122740 {
+    public static void main(String[] args) throws Exception {
+        long time = System.nanoTime();
+        for (int i = 0; i < 1000; i++) {
+            new PropertyDescriptor("name", PropertyDescriptor.class);
+            new PropertyDescriptor("value", Concrete.class);
+        }
+        time -= System.nanoTime();
+        System.out.println("Time (ms): " + (-time / 1000000));
+    }
+
+    public static class Abstract<T> {
+        private T value;
+        public T getValue() {
+            return this.value;
+        }
+        public void setValue(T value) {
+            this.value = value;
+        }
+    }
+
+    private static class Concrete extends Abstract<String> {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Performance/Test7184799.java	Tue Aug 07 20:23:41 2012 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 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
+ * @bug 7184799
+ * @summary Tests just a benchmark of Introspector.getBeanInfo(Class) performance
+ * @author Sergey Malenkov
+ * @run main/manual Test7184799
+ */
+
+import java.beans.Introspector;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class Test7184799 {
+    private static final Class[] TYPES = {
+            Class.class,
+            String.class,
+            Character.class,
+            Boolean.class,
+            Byte.class,
+            Short.class,
+            Integer.class,
+            Long.class,
+            Float.class,
+            Double.class,
+            Collection.class,
+            Set.class,
+            HashSet.class,
+            TreeSet.class,
+            LinkedHashSet.class,
+            Map.class,
+            HashMap.class,
+            TreeMap.class,
+            LinkedHashMap.class,
+            WeakHashMap.class,
+            ConcurrentHashMap.class,
+            Dictionary.class,
+            Exception.class,
+    };
+
+    public static void main(String[] args) throws Exception {
+        long time = System.nanoTime();
+        for (Class type : TYPES) {
+            Introspector.getBeanInfo(type);
+        }
+        time -= System.nanoTime();
+        System.out.println("Time (ms): " + (-time / 1000000));
+    }
+}
--- a/langtools/.hgtags	Tue Aug 07 12:47:45 2012 +0100
+++ b/langtools/.hgtags	Tue Aug 07 20:23:41 2012 -0700
@@ -171,3 +171,4 @@
 7e6be2f239c9a4ac6dec280bd18ec296dd78e464 jdk8-b47
 afb0a523155727d42b1c773f783ff3a7cfab8e86 jdk8-b48
 c72c164ced676d3c360d99b1c52cc80940fc3122 jdk8-b49
+b2d8a270f5f2144e14a1fe97fbda9e4391a5332e jdk8-b50