harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r442092 [1/2] - in /incubator/harmony/enhanced/drlvm/trunk: build/make/components/vm/ vm/gc/ vm/gc/build/ vm/gc/src/ vm/gcv4/ vm/include/open/ vm/interpreter/src/ vm/tests/smoke/gc/ vm/vmcore/include/ vm/vmcore/src/class_support/ vm/vmcore/...
Date Mon, 11 Sep 2006 04:31:38 GMT
Author: geirm
Date: Sun Sep 10 21:31:36 2006
New Revision: 442092

URL: http://svn.apache.org/viewvc?view=rev&rev=442092
Log:
HARMONY-1269

This is an updated version of the GC.  I moved the 
old gc to vm/gcv4 to preserve the history, and 
added the gc code from the zip file.  I also 
applied the additional patch dated 08-29.

Code compiled and passed all tests under debug build.


Added:
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/COPYRIGHT
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/LICENSE
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/NOTICE
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/README.txt   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/build/
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_cache.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_copy.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_forced.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_slide_compact.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/fast_list.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/gc_for_vm.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/gc_types.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/init.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/large_pages_linux.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/large_pages_win32.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/prepare.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/root_set_cache.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/selector.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/slide_compact.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/timer.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/gcv4/
      - copied from r441960, incubator/harmony/enhanced/drlvm/trunk/vm/gc/
Modified:
    incubator/harmony/enhanced/drlvm/trunk/build/make/components/vm/gc.xml
    incubator/harmony/enhanced/drlvm/trunk/vm/include/open/gc.h
    incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interp_stack_trace.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/tests/smoke/gc/LOS.java
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/object_generic.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/object_generic.cpp

Modified: incubator/harmony/enhanced/drlvm/trunk/build/make/components/vm/gc.xml
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/build/make/components/vm/gc.xml?view=diff&rev=442092&r1=442091&r2=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/build/make/components/vm/gc.xml (original)
+++ incubator/harmony/enhanced/drlvm/trunk/build/make/components/vm/gc.xml Sun Sep 10 21:31:36 2006
@@ -83,6 +83,7 @@
         <linker id="linker" extends="common.linker">
             <select os="win">
                 <syslibset libs="advapi32,odbc32,ws2_32,mswsock" />
+                <libset libs="${vm.vmcore.lib}" dir="${vm.vmcore.libdir}" />
             </select>
 
             <select os="win" arch="ipf">
@@ -94,7 +95,6 @@
                 <syslibset libs="msvcrtd" />
             </select>
 
-            <libset libs="${vm.vmcore.lib}" dir="${vm.vmcore.libdir}" />
             <libset libs="${vm.hythr.lib}" dir="${vm.hythr.libdir}" />
             <select os="lnx">
                 <linkerarg value="-Bsymbolic" />

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/COPYRIGHT
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/COPYRIGHT?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/COPYRIGHT (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/COPYRIGHT Sun Sep 10 21:31:36 2006
@@ -0,0 +1,5 @@
+    The following copyright notice(s) were affixed to portions of the  
+    code with which this file is now or was at one time distributed and  
+    are placed here unaltered.
+ 
+         (C) Copyright 2005-2006 Intel Corporation

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/LICENSE
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/LICENSE?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/LICENSE (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/LICENSE Sun Sep 10 21:31:36 2006
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+ 
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ 
+   1. Definitions.
+ 
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+ 
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+ 
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+ 
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+ 
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+ 
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+ 
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+ 
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+ 
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+ 
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+ 
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+ 
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+ 
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+ 
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+ 
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+ 
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+ 
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+ 
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+ 
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+ 
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+ 
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+ 
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+ 
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+ 
+   END OF TERMS AND CONDITIONS
+ 
+   APPENDIX: How to apply the Apache License to your work.
+ 
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+ 
+   Copyright [yyyy] [name of copyright owner]
+ 
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+ 
+       http://www.apache.org/licenses/LICENSE-2.0
+ 
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/NOTICE
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/NOTICE?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/NOTICE (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/NOTICE Sun Sep 10 21:31:36 2006
@@ -0,0 +1,7 @@
+     This product includes software developed by The Apache Software 
+     Foundation (http://www.apache.org/).
+ 
+     Portions of Harmony were originally developed by
+     Intel Corporation and are licensed to the Apache Software
+     Foundation under the "Software Grant and Corporate Contribution 
+     License Agreement", informally known as the "Intel Harmony CLA".

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/README.txt
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/README.txt?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/README.txt (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/README.txt Sun Sep 10 21:31:36 2006
@@ -0,0 +1,112 @@
+INTEL CONTRIBUTION TO APACHE HARMONY
+          August 17, 2006
+======================================
+ 
+This archive contains the contribution to the Apache Harmony project from
+Intel. The contribution contains a new garbage collector to be used with DRLVM.
+
+The garbage collector, GC V4.1 is a single-threaded
+stop-the-world adaptive copying / slide compacting collector with dynamic
+algorithm switching. 
+
+GC V4.1 was developed by Ivan Volosyuk and is roughly one third the size of GC
+V4. It addresses specific performance problems of GC V4.  For example, there
+are fewer:
+ * full heap passes (1 pass in the common case)
+ * atomic exchanges during GC
+ * fewer bit shifts.
+
+GC V4.1 has basic implementations of:
+ * weak references
+ * finalizible objects
+ * object pinning
+
+The design of GC V4.1 is similar to: "P. Sansom. Dual-Mode Garbage Collection.
+In Third Int. Workshop on the Parallel Implementation of Functional Languages,
+pages 238 -- 310, University  Southampton, U.K., September 1991."  This design
+was chosen for expedient development.
+
+Basic GC terminology and concepts in this collector are from:
+"Paul R. Wilson. Uniprocessor garbage collection techniques. In Proc of
+International Workshop on Memory Management in the Springer-Verlag Lecture
+Notes in Computer Science series., St. Malo, France, September 1992"
+
+GC V4.1 is a drop-in replacement for GC V4. In limited testing, GC V4.1
+delivers better performance than GC V4 on UP and SMP hardware.
+
+GC V4 functions that were reused include spin lock implementation,
+parameter parsing code, class preparation, fast list.
+
+0. QUICK START
+--------------
+In the <DRLVM> root directory, replace the gc/ directory with the content
+of the archive by executing the following commands:
+
+  cd incubator/harmony/enhanced/drlvm/trunk/vm
+  rm -rf gc
+  unzip gcv4.1.zip
+
+Build and use DRLVM as usual.
+
+1. ARCHIVE CONTENTS
+-------------------
+Archive contains the GC V4.1 source files. 
+
+Supported architectures: Linux*/IA-32, Windows*/IA-32.
+
+The layout of archive is following:
+  <gcv4.1.zip>
+   src/*.cpp, *.h  - C++ sources of GC V4.1
+
+
+2. TOOLS AND ENVIRONMENT VARIABLES REQUIRED FOR THE BUILD
+---------------------------------------------------------
+This collector requires the Harmony class libraries and DRLVM. 
+Please, follow the usual build process for DRLVM to build this module as a part
+of DRLVM. Tools and environment variable are exactly the same as for DRLVM.
+
+3. BUILDING GC V4.1
+------------------
+Build GC V4.1 as a part of DRLVM by doing the following:
+  
+  3.1 Replace GC V4 with GC V4.1.
+      Remove the gc/ directory from <DRLVM>/vm/gc. Unpack the archive into 
+      the <DRLVM>/vm directory. The gc/ directory appears there.
+
+  3.2 Follow the usual DRLVM build process. Consult <DRLVM>/README.txt for
+      details.
+
+4. RUNNING GC V4.1
+-----------------
+You can use the new GC V4.1 collector with DRLVM just as GC V4.
+
+5. BUILDING AND RUNNING TESTS
+-----------------------------
+All existing tests for DRLVM should work OK.
+
+Note: 
+    The test gc.LOS from DRLVM smoke tests is known to have issues with GC.
+    The test verifies that the space available for large objects is not less
+    then that for small objects. GC V4.1 does not differentiate between small
+    and large objects but contains an optimization for the out-of-heap
+    condition: OutOfMemoryError can be thrown even when some space is still
+    available on the heap, which causes the test to fail. Exclude gc.LOS
+    from the test run until it is fixed.
+
+6. KNOWN ISSUES
+---------------
+Detailed descriptions of the algorithms used is missing.
+Synchronization on simultaneous pinning and hashcode creation is not yet
+implemented. Per object recursion counter is limited by 7 iterations.
+At present, the system will abort on pin counter overflow.
+
+7. TODO
+-------
+Try additional benchmarks, investigate performance problems.
+
+8. DISCLAIMER AND LEGAL INFORMATION
+-----------------------------------
+*) Other brands and names are the property of their respective owners.
+
+
+

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/gc/README.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.cpp?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.cpp Sun Sep 10 21:31:36 2006
@@ -0,0 +1,402 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ivan Volosyuk
+ */
+
+#include <vector>
+#include <open/vm_gc.h>
+#include <jni_types.h>
+#include "gc_types.h"
+#include "collect.h"
+#include "timer.h"
+#include <stdio.h>
+
+fast_list<Partial_Reveal_Object**,65536> slots;
+reference_vector soft_references;
+reference_vector weak_references;
+reference_vector phantom_references;
+reference_vector to_finalize;
+
+std::vector<unsigned char*> pinned_areas;
+fast_list<unsigned char*, 1024> pinned_areas_unsorted;
+unsigned pinned_areas_pos = 0;
+
+std::vector<unsigned char*> old_pinned_areas;
+unsigned old_pinned_areas_pos = 0;
+
+int gc_num = 0;
+apr_time_t total_gc_time = 0;
+apr_time_t total_user_time = 0;
+apr_time_t last_gc_time = 0;
+apr_time_t last_user_time = 0;
+apr_time_t max_gc_time = 0;
+int object_count = 0;
+int soft_refs = 0;
+int weak_refs = 0;
+int phantom_refs = 0;
+apr_time_t gc_start, gc_end;
+
+enum GC_TYPE gc_type;
+
+void
+gc_time_start_hook(apr_time_t *start_time) {	
+	*start_time = apr_time_now();
+}
+
+
+apr_time_t
+gc_time_end_hook(const char *event, apr_time_t *start_time, apr_time_t *end_time)
+{	
+    *end_time = apr_time_now();
+    apr_time_t time =  *end_time - *start_time;
+    INFO2("gc.time", time/1000 << " ms, " << event);
+    //INFO2("gc.objs", "Live objects = " << object_count);
+    return time;
+}
+
+void notify_gc_start()
+{
+    gc_num++;
+    last_gc_time = 0;
+
+    gc_time_start_hook(&gc_start);
+    last_user_time = gc_start - gc_end;
+    if (gc_num == 1) {
+        timer_calibrate(last_user_time);
+    }
+}
+
+const char *gc_name(GC_TYPE gc_type) {
+    switch (gc_type) {
+        case GC_COPY: return "COPY";
+        case GC_FORCED: return "FORCED";
+        case GC_FULL: return "FULL";
+        case GC_SLIDE_COMPACT: return "COMPACT";
+        default: return "UNKNOWN";
+    };
+}
+
+void notify_gc_end() {
+    last_gc_time = gc_time_end_hook("GC", &gc_start, &gc_end);
+
+    if (last_gc_time > max_gc_time) max_gc_time = last_gc_time;
+    total_gc_time += last_gc_time;
+    total_user_time += last_user_time;
+
+    const char *gc_type_str = gc_name(gc_type);
+    
+    INFO2("gc.verbose", "GC " << gc_type_str << " ["
+            << (gc_num - 1) << "]: " << last_gc_time/1000 << " ms, "
+        "User " << last_user_time/1000 << " ms, "
+        "Total GC " << total_gc_time/1000 << " ms, "
+        "Total User " << total_user_time/1000 << " ms, "
+        "Used " << ((int64)heap.size - gc_free_memory()) / 1024 / 1024 << " mb"
+    );
+}
+
+void clear_thread_local_buffers() {
+    GC_Thread_Info *info = thread_list;
+    while(info) {
+        info->tls_current_free = 0;
+        info->tls_current_ceiling = 0;
+        info = info->next;
+    }
+}
+
+static void enumerate_universe() {
+    if (remember_root_set) {
+        // remember root set before doing modifications in heap
+        gc_cache_retrieve_root_set();
+        gc_cache_emit_root_set();
+    } else {
+        // default behaviour
+        vm_enumerate_root_set_all_threads();
+    }
+}
+
+void process_finalizible_objects_on_exit() {
+    vm_gc_lock_enum();
+    // FIXME: leak of processed objects.
+    for(reference_vector::iterator i = finalizible_objects.begin();
+            i != finalizible_objects.end(); ++i) {
+
+        Partial_Reveal_Object *obj = *i;
+        if (!obj) continue;
+        vm_finalize_object((Managed_Object_Handle)obj);
+    }
+    finalizible_objects.clear();
+    vm_gc_unlock_enum();
+}
+
+void process_finalizable_objects() {
+    // FIXME: leak of processed objects.
+    for(reference_vector::iterator i = finalizible_objects.begin();
+            i != finalizible_objects.end();) {
+
+        Partial_Reveal_Object *obj = *i;
+        if (!obj) { ++i; continue; }
+
+        int info = obj->obj_info();
+        if (info & heap_mark_phase) {
+            // marked
+            TRACE2("gc.debug", "0x" << obj << " referenced from finalizible objects (marked)");
+            gc_add_root_set_entry((Managed_Object_Handle*)&*i, false);
+        } else {
+            // not marked
+            TRACE2("gc.debug", "0x" << obj << " referenced from finalizible objects (unmarked)");
+            to_finalize.push_back(obj);
+            gc_add_root_set_entry((Managed_Object_Handle*)&to_finalize.back(), false);
+
+            // removing this object from vector, replacing it with last one.
+            *i = finalizible_objects.pop_back();
+            continue; // without promotion of iterator
+        }
+        ++i;
+    }
+    if (!to_finalize.empty()) {
+        pending_finalizers = true;
+        TRACE2("gc.finalize", to_finalize.count() << " objects to be finalized");
+    }
+}
+
+void finalize_objects() {
+    for(reference_vector::iterator i = to_finalize.begin();
+            i != to_finalize.end(); ++i) {
+        vm_finalize_object((Managed_Object_Handle)*i);
+    }
+    to_finalize.clear();
+}
+
+void process_special_references(reference_vector& array) {
+    for(reference_vector::iterator i = array.begin();
+            i != array.end(); ++i) {
+        Partial_Reveal_Object *ref = *i;
+
+        Partial_Reveal_Object **referent = (Partial_Reveal_Object**) ((Ptr)ref + global_referent_offset);
+        Partial_Reveal_Object* obj = *referent;
+
+        if (obj == 0) {
+            // reference already cleared
+            continue;
+        }
+
+        int info = obj->obj_info();
+        if (info & heap_mark_phase) {
+            // object marked, is it moved?
+            int vt = obj->vt();
+            if (!(vt & FORWARDING_BIT)) continue;
+            // moved, updating referent field
+            *referent = (Partial_Reveal_Object*)(vt & ~FORWARDING_BIT);
+            continue;
+        }
+
+        // object not marked
+        *referent = 0;
+        TRACE2("gc.ref", "process_special_references: reference enquequed");
+        vm_enqueue_reference((Managed_Object_Handle*)ref);
+    }
+}
+
+// scan only finalizible object, without enqueue
+void scan_finalizible_objects() {
+    for(reference_vector::iterator i = finalizible_objects.begin();
+            i != finalizible_objects.end();++i) {
+        gc_add_root_set_entry((Managed_Object_Handle*) &*i, false);
+    }
+}
+
+static void prepare_gc() {
+    notify_gc_start(); 
+
+    object_count = 0;
+    soft_references.clear();
+    weak_references.clear();
+    phantom_references.clear();
+    soft_refs = weak_refs = phantom_refs = 0;
+}
+
+unsigned char*
+try_alloc(int size) {
+    unsigned char *res;
+    TRACE2("gc.oome", "heap.pos = " << heap.pos << " heap.base = " << heap.base <<
+            " max_heap_size = " << heap.max_size << " heap.pos - heap.base = " << (heap.pos - heap.base));
+    TRACE2("gc.oome", "max_heap_size / 100 = " << (heap.max_size) / 100
+            << " (heap.pos - heap.base) / 85 = " << (heap.pos - heap.base) / 85);
+#if 1
+    if ((size_t)(heap.pos - heap.base) / 85 > (heap.max_size) / 100) {
+        TRACE2("gc.oome", "Returning Zero");
+        res = 0;
+    } else
+#endif
+    if (heap.pos + size <= heap.pos_limit) {
+        res = heap.pos;
+        heap.pos += size;
+    } else {
+        res = allocate_from_chunk(size);
+    }
+    return res;
+}
+    
+
+unsigned char *full_gc(int size) {
+    Timer gc_time("FULL_GC", "gc.time.total");
+    heap.old_objects.end = heap.old_objects.pos = heap.old_objects.pos_limit = heap.base;
+    unsigned char *res = slide_gc(size);
+
+    heap.Tcompact = (float) gc_time.dt();
+    heap.working_set_size = (float) (heap.old_objects.end - heap.base);
+    return res;
+}
+
+static unsigned char*
+finish_slide_gc(int size, int stage) {
+    if (stage == 0) {
+        gc_slide_process_special_references(soft_references);
+        gc_slide_process_special_references(weak_references);
+        process_finalizable_objects();
+    }
+    gc_slide_process_special_references(phantom_references);
+
+    TIME(gc_slide_move_all,());
+    gc_slide_postprocess_special_references(soft_references);
+    gc_slide_postprocess_special_references(weak_references);
+    finalize_objects();
+    gc_slide_postprocess_special_references(phantom_references);
+    gc_process_interior_pointers();
+    gc_deallocate_mark_bits();
+
+    heap_mark_phase ^= 3;
+    // reset thread-local allocation areas
+    clear_thread_local_buffers();
+    after_slide_gc();
+
+    unsigned char *res = try_alloc(size);
+
+    vm_resume_threads_after();
+    notify_gc_end();
+    TRACE2("gc.mem", "finish_slide_compact = " << res);
+    return res;
+}
+
+unsigned char *slide_gc(int size) {
+    Timer gc_time("SLIDE_GC", "gc.time.total");
+    prepare_gc();
+
+    pinned_areas.clear();
+    pinned_areas_unsorted.clear();
+    gc_type = GC_SLIDE_COMPACT;
+    gc_allocate_mark_bits();
+    gc_reset_interior_pointers();
+
+    TIME(enumerate_universe,());
+    return finish_slide_gc(size, 0);
+}
+
+void transition_copy_to_sliding_compaction(fast_list<Partial_Reveal_Object**,65536>& slots) {
+    INFO2("gc.verbose", "COPY -> COMP on go transition");
+    gc_type = GC_SLIDE_COMPACT;
+    gc_allocate_mark_bits();
+    gc_reset_interior_pointers();
+    gc_slide_process_transitional_slots(slots);
+}
+
+unsigned char *copy_gc(int size) {
+    Timer gc_time("COPY_GC", "gc.time.total");
+    prepare_gc();
+    TRACE2("gc.debug", "limits 0x" << heap.compaction_region_start() << " 0x" << heap.compaction_region_end());
+
+    pinned_areas.clear();
+    pinned_areas_unsorted.clear();
+
+    gc_type = GC_COPY;
+    TIME(enumerate_universe,());
+
+    if (gc_type == GC_SLIDE_COMPACT) {
+        unsigned char *res = finish_slide_gc(size, 0);
+        heap.Tcopy = (float) gc_time.dt();
+        return res;
+    }
+    process_special_references(soft_references);
+    process_special_references(weak_references);
+    process_finalizable_objects();
+    if (gc_type == GC_SLIDE_COMPACT) {
+        unsigned char *res = finish_slide_gc(size, 1);
+        heap.Tcopy = (float) gc_time.dt();
+        return res;
+    }
+    finalize_objects();
+    process_special_references(phantom_references);
+
+    heap_mark_phase ^= 3;
+    gc_copy_update_regions();
+    after_copy_gc();
+    // reset thread-local allocation areas
+    clear_thread_local_buffers();
+
+    unsigned char *res = try_alloc(size);
+    vm_resume_threads_after();
+    notify_gc_end();
+    TRACE2("gc.mem", "copy_gc = " << res);
+    heap.Tcopy = (float) gc_time.dt();
+    return res;
+}
+
+void force_gc() {
+    Timer gc_time("FORCE_GC", "gc.time.total");
+    prepare_gc();
+
+    gc_type = GC_FORCED;
+    TIME(enumerate_universe,());
+    TIME(process_special_references,(soft_references));
+    TIME(process_special_references,(weak_references));
+    TIME(process_finalizable_objects,());
+    TIME(process_special_references,(phantom_references));
+    TIME(finalize_objects,());
+
+    heap_mark_phase ^= 3;
+    // reset thread-local allocation areas
+    //clear_thread_local_buffers();
+
+    TIME(vm_resume_threads_after,());
+    notify_gc_end();
+}
+
+void gc_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned) {
+    //Partial_Reveal_Object **ref1 = (Partial_Reveal_Object**)ref;
+    switch(gc_type) {
+        case GC_COPY: gc_copy_add_root_set_entry(ref, is_pinned); break;
+        case GC_FORCED: gc_forced_add_root_set_entry(ref, is_pinned); break;
+        case GC_SLIDE_COMPACT: gc_slide_add_root_set_entry(ref, is_pinned); break;
+        case GC_CACHE: gc_cache_add_root_set_entry(ref, is_pinned); break;
+                      
+        case GC_FULL:
+        default: abort();
+    }
+}
+
+void gc_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned)
+{
+    switch (gc_type) {
+        case GC_COPY: gc_copy_add_root_set_entry_interior_pointer(slot, offset, is_pinned); break;
+        case GC_FORCED: gc_forced_add_root_set_entry_interior_pointer(slot, offset, is_pinned); break;
+        case GC_SLIDE_COMPACT: gc_slide_add_root_set_entry_interior_pointer(slot, offset, is_pinned); break;
+        case GC_CACHE: gc_cache_add_root_set_entry_interior_pointer(slot, offset, is_pinned); break;
+
+        case GC_FULL:
+        default: abort();
+    }
+}

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.h?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.h Sun Sep 10 21:31:36 2006
@@ -0,0 +1,91 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ivan Volosyuk
+ */
+
+#include <open/vm.h>
+#include "gc_types.h"
+#include "fast_list.h"
+#include <assert.h>
+#include <open/gc.h>
+#include <open/types.h>
+
+extern fast_list<Partial_Reveal_Object**,65536> slots;
+typedef fast_list<Partial_Reveal_Object*,1024> reference_vector;
+extern reference_vector finalizible_objects;
+extern reference_vector soft_references;
+extern reference_vector weak_references;
+extern reference_vector phantom_references;
+extern int soft_refs;
+extern int weak_refs;
+extern int phantom_refs;
+extern int object_count;
+typedef fast_list<unsigned char*,1024> pinned_areas_unsorted_t;
+extern pinned_areas_unsorted_t pinned_areas_unsorted;
+
+inline void add_reference_to_list(Partial_Reveal_Object* obj, 
+        reference_vector& references)
+{
+    TRACE2("gc.debug", "0x" << obj << " referenced from weak reference <unknown>");
+    references.push_back(obj);
+}
+
+inline void add_soft_reference(Partial_Reveal_Object *obj) {
+    //TRACE2("gc.ref.alive", "add_soft_reference("<< obj << ")");
+    add_reference_to_list(obj, soft_references);
+}
+
+inline void add_phantom_reference(Partial_Reveal_Object *obj) {
+    //TRACE2("gc.ref.alive", "add_phantom_reference("<< obj << ")");
+    add_reference_to_list(obj, phantom_references);
+}
+
+inline void add_weak_reference(Partial_Reveal_Object *obj) {
+    //TRACE2("gc.ref.alive", "add_weak_reference("<< obj << ")");
+    add_reference_to_list(obj, weak_references);
+}
+
+inline void assert_vt(Partial_Reveal_Object *obj) {
+    assert(obj->vt() & ~(FORWARDING_BIT|RESCAN_BIT));
+    assert(!(obj->vt() & (FORWARDING_BIT|RESCAN_BIT)));
+}
+
+void gc_copy_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned);
+void gc_copy_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned);
+void gc_copy_update_regions();
+
+void gc_forced_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned);
+void gc_forced_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned);
+
+void gc_reset_interior_pointers();
+void gc_process_interior_pointers();
+void gc_slide_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned);
+void gc_slide_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned);
+void gc_slide_move_all();
+void gc_slide_process_special_references(reference_vector& array);
+void gc_slide_postprocess_special_references(reference_vector& array);
+
+void transition_copy_to_sliding_compaction(fast_list<Partial_Reveal_Object**,65536>& slots);
+void gc_slide_process_transitional_slots(fast_list<Partial_Reveal_Object**,65536>& slots);
+void gc_slide_process_transitional_slots(Partial_Reveal_Object **refs, int pos, int length);
+
+void gc_cache_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned);
+void gc_cache_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned);
+void gc_cache_retrieve_root_set();
+void gc_cache_emit_root_set();
+
+void gc_forced_mt_mark_scan();

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_cache.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_cache.cpp?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_cache.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_cache.cpp Sun Sep 10 21:31:36 2006
@@ -0,0 +1,71 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ivan Volosyuk
+ */
+
+#include <assert.h>
+#include <vector>
+#include <algorithm>
+#include <open/vm_gc.h>
+#include <apr_time.h>
+#include <jni_types.h>
+#include "gc_types.h"
+#include "collect.h"
+#include "slide_compact.h"
+#include "root_set_cache.h"
+
+roots_vector root_set;
+fast_list<InteriorPointer,256> interior_pointers;
+
+void gc_cache_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned) {
+    assert(!is_pinned);
+    assert(ref != NULL);
+    assert(*ref == NULL || ((unsigned char*)*ref >= heap.base && (unsigned char*)*ref < heap.ceiling));
+    root_set.push_back((Partial_Reveal_Object**)ref);
+}
+
+void gc_cache_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned)
+{
+    assert(!is_pinned);
+    InteriorPointer ip;
+    ip.obj = (Partial_Reveal_Object*) (*(unsigned char**)slot - offset);
+    ip.interior_ref = (Partial_Reveal_Object**)slot;
+    ip.offset = offset;
+    interior_pointers.push_back(ip);
+}
+
+void gc_cache_emit_root_set() {
+    for(roots_vector::iterator r = root_set.begin(); r != root_set.end(); ++r) {
+        gc_add_root_set_entry((Managed_Object_Handle*)*r, false);
+    }
+
+    for(fast_list<InteriorPointer,256>::iterator ip = interior_pointers.begin();
+            ip != interior_pointers.end(); ++ip) {
+        gc_add_root_set_entry_interior_pointer ((void**)(*ip).interior_ref, (*ip).offset, false);
+    }
+}
+
+void gc_cache_retrieve_root_set() {
+    root_set.clear();
+    interior_pointers.clear();
+    GC_TYPE orig_gc_type = gc_type;
+    gc_type = GC_CACHE;
+    vm_enumerate_root_set_all_threads();
+    gc_type = orig_gc_type;
+    INFO2("gc.verbose", root_set.count() << " roots collected");
+    INFO2("gc.verbose", interior_pointers.count() << " interior pointers collected");
+}

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_cache.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_copy.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_copy.cpp?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_copy.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_copy.cpp Sun Sep 10 21:31:36 2006
@@ -0,0 +1,311 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ivan Volosyuk
+ */
+
+#include <assert.h>
+#include <vector>
+#include <algorithm>
+#include <open/vm_gc.h>
+#include <apr_time.h>
+#include <jni_types.h>
+#include "gc_types.h"
+#include "collect.h"
+
+void gc_copy_update_regions() {
+    int n = 0;
+    for(fast_list<unsigned char*, 1024>::iterator it = pinned_areas_unsorted.begin();
+            it != pinned_areas_unsorted.end(); ++it) {
+        TRACE2("gc.pin", "pinned area unsorted[" << n << "] = 0x" << *it);
+        n++;
+    }
+    
+    pinned_areas.resize(pinned_areas_unsorted.count());
+    partial_sort_copy(pinned_areas_unsorted.begin(), pinned_areas_unsorted.end(), pinned_areas.begin(), pinned_areas.end());
+
+    for(unsigned i = 0; i < pinned_areas.size(); i++) {
+        TRACE2("gc.pin", "pinned area [" << i << "] = 0x" << pinned_areas[i]);
+    }
+
+    heap.pos = heap.compaction_region_start();
+    heap.pos_limit = pinned_areas.empty() ? heap.compaction_region_end() : (unsigned char*) pinned_areas[0];
+
+    assert(heap.pos >= heap.old_objects.end);
+    assert(heap.old_objects.pos_limit <= heap.old_objects.end);
+    assert(heap.old_objects.pos <= heap.old_objects.end);
+    assert(heap.pos <= heap.pos_limit);
+    pinned_areas_pos = 1;
+    cleaning_needed = true;
+}
+
+static bool gc_copy_process_reference(Partial_Reveal_Object **ref, Boolean is_pinned, int phase);
+
+static inline bool 
+gc_copy_scan_array_object(Partial_Reveal_Object *array, int vector_length, int phase)
+{
+    assert(!is_array_of_primitives(array));
+
+    int32 array_length = vector_length; //vector_get_length((Vector_Handle) array);
+
+    Partial_Reveal_Object **refs = (Partial_Reveal_Object**)
+        vector_get_element_address_ref ((Vector_Handle) array, 0);
+
+    for(int i = 0; i < array_length; i++) {
+        Partial_Reveal_Object **ref = &refs[i];
+
+        bool success = gc_copy_process_reference(ref, false, phase);
+
+        if (!success) {
+            // overflow in old objects
+            // continue transition to sliding compaction
+            gc_slide_process_transitional_slots(refs, i + 1, array_length);
+            return false;
+        }
+    }
+    return true;
+}
+
+bool place_into_old_objects(unsigned char *&newpos,
+                                          unsigned char *&endpos,
+                                          int size) {
+    newpos = heap.old_objects.pos;
+    endpos = newpos + size;
+
+    assert(heap.old_objects.pos_limit <= heap.old_objects.end);
+
+    if (endpos <= heap.old_objects.pos_limit) {
+        heap.old_objects.pos = endpos;
+        assert(endpos <= heap.old_objects.end);
+        return true;
+    }
+    TRACE2("gc.pin.gc", "old area: reached heap.old_objects.pos_limit =" << heap.old_objects.pos_limit);
+
+
+
+    // object doesn't feet in old objects region, skip possibly
+    // pinned objects in old objects region
+    // FIXME: can add 'heap.old_objects.end' to the vector
+    //        one less check
+    while(old_pinned_areas_pos < old_pinned_areas.size()) {
+        assert(heap.old_objects.pos <= old_pinned_areas[old_pinned_areas_pos]);
+
+        heap.old_objects.pos = old_pinned_areas[old_pinned_areas_pos];
+
+        if (old_pinned_areas_pos + 1 < old_pinned_areas.size()) {
+            // more pinned objects exists
+            unsigned char *new_limit = old_pinned_areas[old_pinned_areas_pos + 1];
+            if (new_limit > heap.old_objects.end) {
+                TRACE2("gc.pin.gc", "old area: new limit is greater then heap.old_objects.end = "
+                        << new_limit);
+                heap.old_objects.pos = heap.old_objects.pos_limit;
+                old_pinned_areas_pos += 2;
+                return false;
+            }
+            heap.old_objects.pos_limit = new_limit;
+        } else {
+            heap.old_objects.pos_limit = heap.old_objects.end;
+        }
+        old_pinned_areas_pos += 2;
+        TRACE2("gc.pin.gc", "old area: heap.old_objects.pos =" << heap.old_objects.pos);
+        TRACE2("gc.pin.gc", "old area: heap.old_objects.pos_limit =" << heap.old_objects.pos_limit);
+
+        newpos = heap.old_objects.pos;
+        endpos = newpos + size;
+        if (endpos <= heap.old_objects.pos_limit) {
+            heap.old_objects.pos = endpos;
+            return true;
+        }
+    }
+    return false;
+}
+
+static bool gc_copy_process_reference(Partial_Reveal_Object **ref, Boolean is_pinned, int phase) {
+    assert(ref);
+ 
+    Partial_Reveal_Object* obj = *ref;
+
+    if (!obj) return true;
+    assert(obj->vt() & ~(FORWARDING_BIT|RESCAN_BIT));
+    TRACE2("gc.debug", "0x" << obj << " info = " << obj->obj_info());
+
+    int info = obj->obj_info();
+    int vt = obj->vt();
+
+    if (info & phase) {
+        // object already marked, need to check if it is forwared still
+        
+        if (vt & FORWARDING_BIT) {
+            Partial_Reveal_Object *newpos = (Partial_Reveal_Object*) (vt & ~FORWARDING_BIT);
+            assert_vt(newpos);
+            *ref = newpos;
+        }
+        return true;
+    }
+
+    VMEXPORT Class_Handle vtable_get_class(VTable_Handle vh);
+    assert(class_get_vtable(vtable_get_class((VTable_Handle)obj->vt())) == (VTable_Handle)obj->vt());
+    TRACE2("gc.debug", "0x" << obj << " is " << class_get_name(vtable_get_class((VTable_Handle)obj->vt())));
+
+    obj->obj_info() = (info & ~MARK_BITS) | phase;
+
+    // move the object?
+#define pos ((unsigned char*) obj)
+    Partial_Reveal_VTable *vtable = (Partial_Reveal_VTable*) vt;
+    GC_VTable_Info *gcvt = vtable->get_gcvt();
+
+    if (pos >= heap.compaction_region_start() && pos < heap.compaction_region_end()) {
+        int size = get_object_size(obj, gcvt);
+
+        // is it not pinned?
+        if (size < 5000 &&  (!is_pinned) && ((info & OBJECT_IS_PINNED_BITS) == 0)) {
+            if (info & HASHCODE_IS_SET_BIT) {
+                size += 4;
+            }
+
+            // move the object
+            unsigned char *newpos, *endpos;
+            if (place_into_old_objects(newpos, endpos, size)) {
+
+                TRACE2("gc.debug", "move 0x" << obj << " to 0x" << newpos << " info = " << obj->obj_info());
+
+                Partial_Reveal_Object *newobj = (Partial_Reveal_Object*) newpos;
+                if ((info & HASHCODE_IS_SET_BIT) && !(info & HASHCODE_IS_ALLOCATED_BIT)) {
+                    memcpy(newobj, obj, size-4);
+                    *(int*)(newpos + size-4) = gen_hashcode(obj);
+                    newobj->obj_info() |= HASHCODE_IS_ALLOCATED_BIT;
+                } else {
+                    memcpy(newobj, obj, size);
+                }
+                //TRACE2("gc.copy", "obj " << obj << " -> " << newobj << " + " << size);
+                assert(newobj->vt() == obj->vt());
+                assert(newobj->obj_info() & phase);
+                obj->vt() = (POINTER_SIZE_INT)newobj | FORWARDING_BIT;
+                assert_vt(newobj);
+                *ref = newobj;
+                obj = newobj;
+            } else {
+                // overflow! no more space in old objects area
+                // pinning the overflow object
+                pinned_areas_unsorted.push_back(pos);
+                pinned_areas_unsorted.push_back(pos + size
+                        + ((obj->obj_info() & HASHCODE_IS_ALLOCATED_BIT) ? 4 : 0));
+                TRACE2("gc.pin", "add failed pinned area = " << pos << " " << pinned_areas_unsorted.back());
+                TRACE2("gc.pin", "failed object = " << pos);
+                // arange transition to slide compaction
+                obj->obj_info() &= ~MARK_BITS;
+                slots.push_back(ref);
+                transition_copy_to_sliding_compaction(slots);
+                return false;
+            }
+        } else {
+            TRACE2("gc.debug", "pinned 0x" << obj);
+            assert(gc_num != 1 || !(obj->obj_info() & HASHCODE_IS_ALLOCATED_BIT));
+            pinned_areas_unsorted.push_back(pos);
+            pinned_areas_unsorted.push_back(pos + size
+                    + ((obj->obj_info() & HASHCODE_IS_ALLOCATED_BIT) ? 4 : 0));
+            TRACE2("gc.pin", "add pinned area = " << pos << " " << pinned_areas_unsorted.back() << " hash = " 
+                    << ((obj->obj_info() & HASHCODE_IS_ALLOCATED_BIT) ? 4 : 0));
+        }
+    }
+
+    if (!gcvt->has_slots()) return true;
+
+    if (gcvt->is_array()) {
+        int vector_length = obj->array_length();
+        return gc_copy_scan_array_object(obj, vector_length, phase);
+    }
+
+    WeakReferenceType type = gcvt->reference_type();
+    int *offset_list = gcvt->offset_array();
+
+    // handling special references in objects.
+    if (type != NOT_REFERENCE) {
+        switch (type) {
+            case SOFT_REFERENCE:
+                TRACE2("gc.debug", "soft reference 0x" << obj);
+                add_soft_reference(obj);
+                break;
+            case WEAK_REFERENCE:
+                TRACE2("gc.debug", "weak reference 0x" << obj);
+                add_weak_reference(obj);
+                break;
+            case PHANTOM_REFERENCE:
+                TRACE2("gc.debug", "phantom reference 0x" << obj);
+                add_phantom_reference(obj);
+                break;
+            default:
+                TRACE2("gc.verbose", "Wrong reference type");
+                break;
+        }
+    }
+
+    int offset;
+    while ((offset = *offset_list) != 0) {
+        Partial_Reveal_Object **slot = (Partial_Reveal_Object**)(pos + offset);
+        //if (*slot) { looks like without check is better
+            TRACE2("gc.debug", "0x" << *slot << " referenced from object = 0x" << obj);
+            slots.push_back(slot);
+        //}
+
+        offset_list++;
+    }
+
+    return true;
+#undef pos
+}
+
+static void gc_copy_add_root_set_entry_internal(Partial_Reveal_Object **ref, Boolean is_pinned) {
+    // FIXME: check for zero here, how it reflect perfomance, should be better!
+    // and possibly remove check in gc_copy_process_reference
+    // while added check in array handling
+
+#ifdef _DEBUG
+    if (*ref) {
+        TRACE2("gc.debug", "0x" << *ref << " referenced from root = 0x" << ref << " info = " << (*ref)->obj_info());
+    }
+#endif
+
+    int phase = heap_mark_phase;
+    gc_copy_process_reference(ref, is_pinned, phase);
+
+    while (true) {
+        if (slots.empty()) break;
+        Partial_Reveal_Object **ref = slots.pop_back();
+        *ref;
+        gc_copy_process_reference(ref, false, phase);
+    }
+}
+
+void gc_copy_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned) {
+    assert(!is_pinned);
+    //TRACE2("gc.enum", "gc_add_root_set_entry");
+    gc_copy_add_root_set_entry_internal((Partial_Reveal_Object**)ref, is_pinned);
+}
+
+void gc_copy_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned)
+{
+    assert(!is_pinned);
+    int *ref = (int*)slot;
+    int oldobj = *ref - offset;
+    int newobj = oldobj;
+
+    gc_copy_add_root_set_entry_internal((Partial_Reveal_Object**)&newobj, is_pinned);
+    if (newobj != oldobj) {
+        *ref = newobj + offset;
+    }
+}
+

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_copy.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_forced.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_forced.cpp?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_forced.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_forced.cpp Sun Sep 10 21:31:36 2006
@@ -0,0 +1,133 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ivan Volosyuk
+ */
+
+#include <assert.h>
+#include <vector>
+#include <open/vm_gc.h>
+#include <jni_types.h>
+#include <apr_time.h>
+#include "gc_types.h"
+#include "collect.h"
+
+extern fast_list<Partial_Reveal_Object*, 65536> objects; // FIXME: duplication of memory slots and objects
+                                                  // FIXME: move to header file
+
+static void forced_process_reference(Partial_Reveal_Object *obj, Boolean is_pinned);
+
+static inline void 
+forced_scan_array_object(Partial_Reveal_Object *array, int vector_length)
+{
+    // No primitive arrays allowed
+    assert(!is_array_of_primitives(array));
+
+    int32 array_length = vector_length; //vector_get_length((Vector_Handle) array);
+
+    Partial_Reveal_Object **refs = (Partial_Reveal_Object**)
+        vector_get_element_address_ref ((Vector_Handle) array, 0);
+
+    for(int i = 0; i < array_length; i++) {
+        Partial_Reveal_Object **ref = &refs[i];
+        Partial_Reveal_Object *obj = *ref;
+        if (obj != 0) {
+            forced_process_reference(obj, false);
+        }
+    }
+}
+
+static void forced_process_reference(Partial_Reveal_Object *obj, Boolean is_pinned) {
+    assert(!is_pinned);
+
+    assert(obj->vt() & ~FORWARDING_BIT);
+
+    int info = obj->obj_info();
+    if (info & heap_mark_phase) {
+        return;
+    }
+
+    obj->obj_info() = (info & ~MARK_BITS) | heap_mark_phase;
+
+    Partial_Reveal_VTable *vtable = obj->vtable();
+    GC_VTable_Info *gcvt = vtable->get_gcvt();
+
+    if (gcvt->is_array()) { // is array
+        int vector_length = obj->array_length();
+        if (gcvt->has_slots())
+            forced_scan_array_object(obj, vector_length);
+        return;
+    } else {
+        if (!gcvt->has_slots()) return;
+    }
+
+    // process slots
+
+    WeakReferenceType type = gcvt->reference_type();
+    int *offset_list = gcvt->offset_array();
+
+    // handling special references in objects.
+    if (type != NOT_REFERENCE) {
+        switch (type) {
+            case SOFT_REFERENCE:
+                add_soft_reference(obj);
+                break;
+            case WEAK_REFERENCE:
+                add_weak_reference(obj);
+                break;
+            case PHANTOM_REFERENCE:
+                add_phantom_reference(obj);
+                break;
+            default:
+                TRACE2("gc.verbose", "Wrong reference type");
+                break;
+        }
+    }
+
+    int offset;
+    while ((offset = *offset_list) != 0) {
+        Partial_Reveal_Object **slot = (Partial_Reveal_Object**)(((char*)obj) + offset);
+        offset_list++;
+        Partial_Reveal_Object *object = *slot;
+        if (object != 0) {
+            objects.push_back(object);
+        }
+    }
+}
+
+static void gc_forced_add_root_set_entry_internal(Partial_Reveal_Object *obj, Boolean is_pinned) {
+    forced_process_reference(obj, is_pinned);
+
+    while (!objects.empty()) {
+        Partial_Reveal_Object *obj = objects.pop_back();
+        forced_process_reference(obj, false);
+    }
+}
+
+void gc_forced_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned) {
+    Partial_Reveal_Object *obj = *(Partial_Reveal_Object**)ref;
+    if (obj == 0) return;
+    gc_forced_add_root_set_entry_internal(obj, is_pinned);
+}
+
+void gc_forced_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned)
+{
+    int *ref = (int*)slot;
+    int obj = *ref - offset;
+    if (obj == 0) return;
+
+    gc_forced_add_root_set_entry_internal((Partial_Reveal_Object*)obj, is_pinned);
+}

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_forced.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_slide_compact.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_slide_compact.cpp?view=auto&rev=442092
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_slide_compact.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_slide_compact.cpp Sun Sep 10 21:31:36 2006
@@ -0,0 +1,671 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ivan Volosyuk
+ */
+
+
+#include <assert.h>
+#include <vector>
+#include <algorithm>
+#include <open/vm_gc.h>
+#include <apr_time.h>
+#include <jni_types.h>
+#include "gc_types.h"
+#include "collect.h"
+#include "slide_compact.h"
+
+unsigned char *mark_bits;
+int mark_bits_size;
+fast_list<Partial_Reveal_Object*, 65536> objects;
+static fast_list<InteriorPointer,256> comp_interior_pointers;
+
+static inline bool
+is_compaction_object(Partial_Reveal_Object *refobj) {
+    if ((unsigned char*) refobj < heap.compaction_region_start()) return false;
+    if ((unsigned char*) refobj >= heap.compaction_region_end()) return false; // FIXME: is it ok to remove upper limit?
+    return true;
+}
+
+static inline bool
+is_forwarded_object(Partial_Reveal_Object *obj) {
+    return obj->vt() & FORWARDING_BIT;
+}
+
+static inline void
+update_forwarded_reference(Partial_Reveal_Object *obj, Partial_Reveal_Object **ref) {
+    assert(!(obj->vt() & RESCAN_BIT));
+    assert(obj->vt() & FORWARDING_BIT);
+    *(int*)ref = obj->vt() & ~FORWARDING_BIT;
+}
+
+static inline bool mark_bit_is_set(Partial_Reveal_Object *obj) {
+    int addr = (POINTER_SIZE_INT)obj - (POINTER_SIZE_INT) heap_base;
+    addr >>= 2;
+    int bit = addr & 7; // FIXME: use defines
+    int byte = addr >> 3;
+    return mark_bits[byte] & ((unsigned char)1 << bit);
+}
+
+static inline void enqueue_reference(Partial_Reveal_Object *refobj, Partial_Reveal_Object **ref) {
+    assert(is_compaction_object(refobj));
+    assert(!is_forwarded_object(refobj));
+    //assert(*ref == refobj);
+    assert(refobj->obj_info());
+
+    int &info = refobj->obj_info();
+    *(int*)ref = info;
+    info = (int)ref | heap_mark_phase;
+}
+
+static inline bool is_object_marked(Partial_Reveal_Object *obj) {
+    return obj->obj_info() & heap_mark_phase;
+}
+
+static inline void set_mark_bit(Partial_Reveal_Object *obj) {
+    int addr = (POINTER_SIZE_INT)obj - (POINTER_SIZE_INT) heap_base;
+    addr >>= 2;
+    int bit = addr & 7; // FIXME: use defines
+    int byte = addr >> 3;
+    mark_bits[byte] |=  ((unsigned char) 1 << bit);
+}
+
+static inline bool mark_object(Partial_Reveal_Object *obj) {
+    int phase = heap_mark_phase;
+
+    assert((unsigned char*) obj >= heap_base && (unsigned char*) obj < heap_ceiling);
+    assert(obj->vt() != 0);
+
+    // is object already marked
+    if (obj->obj_info() & phase) {
+        return false;
+    }
+
+    assert(!is_forwarded_object(obj));
+
+    int info = obj->obj_info();
+
+    if (is_compaction_object(obj)) {
+        set_mark_bit(obj);
+
+        if (info & OBJECT_IS_PINNED_BITS) {
+            pinned_areas_unsorted.push_back((unsigned char*)obj);
+            int size = get_object_size(obj, obj->vtable()->get_gcvt());
+            pinned_areas_unsorted.push_back((unsigned char*)obj + size
+                    + ((info & HASHCODE_IS_ALLOCATED_BIT) ? 4 : 0));
+            TRACE2("gc.pin", "add pinned area = " << (unsigned char*)obj << " " << pinned_areas_unsorted.back());
+        }
+
+        info |= MARK_BITS;
+    } else {
+        info = (info & ~MARK_BITS) | phase;
+    }
+    obj->obj_info() = info;
+
+    assert(obj->obj_info() != 0);
+    return true;
+}
+
+static inline void set_rescan_bit(Partial_Reveal_Object *obj) {
+    obj->vt() |= RESCAN_BIT;
+}
+
+static inline void process_reference_queue(Partial_Reveal_Object *newobj, Partial_Reveal_Object *obj) {
+    int info = obj->obj_info();
+    assert(info);
+    assert(info & heap_mark_phase); assert(is_compaction_object(obj));
+
+    while (!(info & prev_mark_phase)) {
+        assert(info);
+        assert(info & heap_mark_phase);
+        Partial_Reveal_Object **ref = (Partial_Reveal_Object**) (info & ~MARK_BITS);
+        info = (int)*ref;
+        *ref = newobj;
+    }
+    obj->obj_info() = info & ~MARK_BITS;
+}
+
+void gc_reset_interior_pointers() { // FIXME: rename
+    comp_interior_pointers.clear();
+}
+
+static void postprocess_array(Partial_Reveal_Object *array, int vector_length, Partial_Reveal_Object *oldobj) {
+    // No primitive arrays allowed
+    assert(!is_array_of_primitives(array));
+    assert(is_compaction_object(array));
+    assert(!is_forwarded_object(array));
+
+    int32 array_length = vector_length; //vector_get_length((Vector_Handle) array);
+
+    Partial_Reveal_Object **refs = (Partial_Reveal_Object**) vector_get_element_address_ref ((Vector_Handle) array, 0);
+
+    for(int i = 0; i < array_length; i++) {
+        Partial_Reveal_Object **ref = &refs[i];
+        POINTER_SIZE_INT refobj_int = (POINTER_SIZE_INT)*ref;
+        POINTER_SIZE_INT refobj_unmarked = refobj_int & ~1;
+        if (refobj_int == refobj_unmarked) continue; // not specially marked reference
+        Partial_Reveal_Object *refobj = (Partial_Reveal_Object*) refobj_unmarked;
+        enqueue_reference(refobj, ref);
+    }
+}
+
+// after moving some objects should be rescaned
+// storing references to this object to the linked list
+// of reverers to the right of this one.
+// oldobj = original position of object:
+// if this object is pinned and referenced object is moved only original
+// position of this object contains valid (unchanged) information of left/right direction
+static void postprocess_object(Partial_Reveal_Object *obj, Partial_Reveal_Object *oldobj) {
+    assert(obj);
+    assert(is_compaction_object(obj));
+    assert(!is_forwarded_object(obj));
+ 
+    assert((unsigned char*) obj >= heap_base && (unsigned char*) obj < heap_ceiling);
+    assert(obj->vt() & RESCAN_BIT);
+    Partial_Reveal_VTable *vtable = (Partial_Reveal_VTable*) (obj->vt() & ~RESCAN_BIT);
+    obj->vt() = (int) vtable;
+    GC_VTable_Info *gcvt = vtable->get_gcvt();
+
+    // process slots
+    assert(gcvt->has_slots());
+
+    if (gcvt->is_array()) {
+        int vector_length = obj->array_length();
+        postprocess_array(obj, vector_length, oldobj);
+        return;
+    }
+
+    if (gcvt->reference_type() != NOT_REFERENCE) {
+        Partial_Reveal_Object **ref = (Partial_Reveal_Object**)((char*)obj + global_referent_offset);
+
+        POINTER_SIZE_INT refobj_int = (POINTER_SIZE_INT)*ref;
+        POINTER_SIZE_INT refobj_unmarked = refobj_int & ~1;
+        if (refobj_int != refobj_unmarked) {
+            Partial_Reveal_Object *refobj = (Partial_Reveal_Object*) refobj_unmarked;
+            enqueue_reference(refobj, ref);
+        }
+    }
+
+    int *offset_list = gcvt->offset_array();
+    int offset;
+    while ((offset = *offset_list) != 0) {
+        Partial_Reveal_Object **ref = (Partial_Reveal_Object**)((char*)obj + offset);
+        offset_list++;
+
+        POINTER_SIZE_INT refobj_int = (POINTER_SIZE_INT)*ref;
+        POINTER_SIZE_INT refobj_unmarked = refobj_int & ~1;
+        if (refobj_int == refobj_unmarked) continue; // not specially marked reference
+        Partial_Reveal_Object *refobj = (Partial_Reveal_Object*) refobj_unmarked;
+        enqueue_reference(refobj, ref);
+    }
+}
+
+void gc_slide_move_all() {
+    unsigned char *compact_pos = heap.compaction_region_start();
+    unsigned char *compact_pos_limit = heap.compaction_region_end();
+    unsigned char *next_pinned_object = heap.ceiling;
+    unsigned next_pinned_object_pos = 0;
+
+    prev_mark_phase = heap_mark_phase ^ 3;
+    pinned_areas_pos = 1;
+    if (pinned_areas.size() != 0) compact_pos_limit = pinned_areas[0];
+
+#if _DEBUG
+    int pin_size = 0;
+    for(pinned_areas_unsorted_t::iterator iii = pinned_areas_unsorted.begin();
+            iii != pinned_areas_unsorted.end(); ++iii) {
+        unsigned char *start = *iii; ++iii;
+        unsigned char *end = *iii;
+        pin_size += end - start;
+    }
+#endif
+
+    pinned_areas.resize(pinned_areas_unsorted.count());
+    partial_sort_copy(pinned_areas_unsorted.begin(), pinned_areas_unsorted.end(), pinned_areas.begin(), pinned_areas.end());
+
+#if _DEBUG
+    int sorted_pin_size = 0;
+    for(unsigned ii = 0; ii < pinned_areas.size(); ii+=2) {
+        TRACE2("gc.pin", "pinned_areas[" << ii << "] = " << pinned_areas[ii]);
+        TRACE2("gc.pin", "pinned_areas[" << ii+1 << "] = " << pinned_areas[ii+1]);
+        sorted_pin_size += pinned_areas[ii+1] - pinned_areas[ii];
+    }
+    assert(pin_size == sorted_pin_size);
+#endif
+
+    for(unsigned i = 0; i < pinned_areas.size(); i+=2) {
+        unsigned char *obj_start = pinned_areas[i];
+        if ((unsigned char*)obj_start < compact_pos) {
+            assert(pinned_areas[i+1] <= compact_pos);
+            continue;
+        }
+        compact_pos_limit = obj_start;
+        pinned_areas_pos = i + 1;
+        next_pinned_object = obj_start;
+        next_pinned_object_pos = i;
+        TRACE2("gc.pin", "next pinned object " << next_pinned_object_pos << " = " << next_pinned_object);
+        break;
+    }
+
+    pinned_areas.push_back(heap.ceiling);
+
+    int *mark_words = (int*) mark_bits;
+    // Searching marked bits
+    int start = (heap.compaction_region_start() - heap_base) / sizeof(void*) / sizeof(int) / 8;
+    int end = (heap.compaction_region_end() - heap_base + sizeof(void*) + sizeof(int) * 8 - 1) / sizeof(void*) / sizeof(int) / 8;
+    if (end > mark_bits_size/4) end = mark_bits_size/4;
+    for(int i = start; i < end; i++) {
+        // no marked bits in word - skip
+
+        int word = mark_words[i];
+        if (word == 0) continue;
+
+        for(int bit = 0; bit < 32; bit++) {
+            if (word & 1) {
+                unsigned char *pos = heap_base + i * 32 * 4 + bit * 4;
+                Partial_Reveal_Object *obj = (Partial_Reveal_Object*) pos;
+
+                int vt = obj->vt();
+                bool post_processing = vt & RESCAN_BIT;
+                Partial_Reveal_VTable *vtable = (Partial_Reveal_VTable*)(vt & ~RESCAN_BIT);
+                int size = get_object_size(obj, vtable->get_gcvt());
+
+                assert(is_object_marked(obj));
+                assert(!is_forwarded_object(obj));
+
+                if ((unsigned char*)obj != next_pinned_object) {
+
+                    // 4 bytes reserved for hash
+                    while (compact_pos + size > compact_pos_limit) {
+                        assert(pinned_areas_pos < pinned_areas.size());
+                        compact_pos = pinned_areas[pinned_areas_pos];
+                        compact_pos_limit = pinned_areas[pinned_areas_pos+1];
+                        pinned_areas_pos += 2;
+                    }
+                    
+                    Partial_Reveal_Object *newobj;
+
+                    if (compact_pos >= pos) {
+                        newobj = obj;
+                        process_reference_queue(obj, obj);
+                        int info = obj->obj_info();
+                        if (compact_pos == pos) {
+                            assert(HASHCODE_IS_ALLOCATED_BIT == 4);
+                            compact_pos += size + (info & HASHCODE_IS_ALLOCATED_BIT);
+                        } else {
+                            assert(compact_pos >= pos + size);
+                        }
+                    } else {
+                        unsigned char *newpos = compact_pos;
+                        compact_pos += size;
+
+                        newobj = (Partial_Reveal_Object*) newpos;
+                        process_reference_queue(newobj, obj);
+                        int info = obj->obj_info();
+
+                        if (info & HASHCODE_IS_SET_BIT) {
+                            size += 4;
+                            compact_pos += 4;
+                        }
+
+                        if (newpos + size <= pos) {
+                            memcpy(newpos, pos, size);
+                        } else {
+                            memmove(newpos, pos, size);
+                        }
+                        if (info & HASHCODE_IS_SET_BIT && !(info & HASHCODE_IS_ALLOCATED_BIT)) {
+                            *(int*)(newpos + size - 4) = gen_hashcode(pos);
+                            newobj->obj_info() |= HASHCODE_IS_ALLOCATED_BIT;
+                        }
+                    }
+
+                    if (post_processing) postprocess_object(newobj, obj);
+                    else assert(!(newobj->vt() & RESCAN_BIT));
+                    assert(!(newobj->vt() & RESCAN_BIT));
+                    assert(!(newobj->obj_info() & OBJECT_IS_PINNED_BITS));
+                } else {
+                    process_reference_queue(obj, obj);
+                    if (obj->vt() & RESCAN_BIT) postprocess_object(obj, obj);
+                    obj->vt() &= ~RESCAN_BIT;
+                    next_pinned_object_pos += 2;
+                    next_pinned_object = pinned_areas[next_pinned_object_pos];
+                }
+
+                // FIXME: is it really speedup?
+                if (!(word >> 1)) break;
+            }
+            word >>= 1;
+        }
+    }
+    assert(next_pinned_object >= heap.compaction_region_end());
+    pinned_areas.pop_back(); //heap.ceiling
+
+    TRACE2("gc.mem", "compaction: region size = "
+            << (heap.compaction_region_end() - heap.compaction_region_start()) / 1024 / 1024 << " mb");
+    TRACE2("gc.mem", "compaction: free_space = "
+            << (heap.ceiling - compact_pos) / 1024 / 1024 << " mb");
+
+    cleaning_needed = true;
+    heap.pos = compact_pos;
+    heap.pos_limit = compact_pos_limit;
+
+    heap.old_objects.end = compact_pos;
+    heap.old_objects.pos = compact_pos;
+    heap.old_objects.pos_limit = compact_pos;
+
+    old_pinned_areas.clear();
+    old_pinned_areas_pos = 1;
+}
+
+static void slide_process_object(Partial_Reveal_Object *obj, Boolean is_pinned);
+
+static inline void 
+slide_scan_array_object(Partial_Reveal_Object *array, Partial_Reveal_VTable *vtable, int vector_length)
+{
+    // No primitive arrays allowed
+    assert(!is_array_of_primitives(array));
+    assert(!is_forwarded_object(array));
+
+    int32 array_length = vector_length; //vector_get_length((Vector_Handle) array);
+
+    Partial_Reveal_Object **refs = (Partial_Reveal_Object**) vector_get_element_address_ref ((Vector_Handle) array, 0);
+
+    if (is_compaction_object(array)) {
+        bool rescan = false;
+        for(int i = 0; i < array_length; i++) {
+            Partial_Reveal_Object **ref = &refs[i];
+            Partial_Reveal_Object *refobj = *ref;
+            if (!refobj) continue;
+
+            if (mark_object(refobj)) {
+                slide_process_object(refobj, false);
+            } else if (is_forwarded_object(refobj)) {
+                update_forwarded_reference(refobj, ref);
+                continue;
+            }
+
+            if (is_compaction_object(refobj)) {
+                if (is_left_object(refobj, ref)) {
+                    enqueue_reference(refobj, ref);
+                } else {
+                    // mark_rescan_reference
+                    *ref = (Partial_Reveal_Object*) ((size_t)refobj | 1);
+                    rescan = true;
+                }
+            }
+        }
+        if (rescan) set_rescan_bit(array);
+    } else {
+        for(int i = 0; i < array_length; i++) {
+            Partial_Reveal_Object **ref = &refs[i];
+            Partial_Reveal_Object *refobj = *ref;
+            if (!refobj) continue;
+
+            if (mark_object(refobj)) {
+                slide_process_object(refobj, false);
+            } else if (is_forwarded_object(refobj)) {
+                update_forwarded_reference(refobj, ref);
+                continue;
+            }
+
+            if (is_compaction_object(refobj)) {
+                enqueue_reference(refobj, ref);
+            }
+        }
+    }
+}
+
+static void slide_process_object(Partial_Reveal_Object *obj, Boolean is_pinned) {
+
+    assert(!is_pinned);
+    assert(obj);
+    assert((unsigned char*) obj >= heap_base && (unsigned char*) obj < heap_ceiling);
+    assert(is_object_marked(obj));
+    //assert(mark_bit_is_set(obj) || !is_compaction_object(obj));
+
+    int vt = obj->vt();
+    assert(obj->vt() & ~RESCAN_BIT); // has vt
+
+    Partial_Reveal_VTable *vtable = (Partial_Reveal_VTable*) (vt & ~RESCAN_BIT);
+    GC_VTable_Info *gcvt = vtable->get_gcvt();
+
+    // process slots
+    if (!gcvt->has_slots()) return;
+
+    if (gcvt->is_array()) {
+        int vector_length = obj->array_length();
+        slide_scan_array_object(obj, vtable, vector_length);
+        return;
+    }
+
+
+    WeakReferenceType type = gcvt->reference_type();
+    int *offset_list = gcvt->offset_array();
+
+    // handling special references in objects.
+    if (type != NOT_REFERENCE) {
+        switch (type) {
+            case SOFT_REFERENCE:
+                add_soft_reference(obj);
+                soft_refs++;
+                break;
+            case WEAK_REFERENCE:
+                add_weak_reference(obj);
+                weak_refs++;
+                break;
+            case PHANTOM_REFERENCE:
+                add_phantom_reference(obj);
+                phantom_refs++;
+                break;
+            default:
+                TRACE2("gc.verbose", "Wrong reference type");
+                break;
+        }
+    }
+
+    if (is_compaction_object(obj)) {
+        bool rescan = false;
+        int offset;
+        while ((offset = *offset_list) != 0) {
+            Partial_Reveal_Object **ref = (Partial_Reveal_Object**)((char*)obj + offset);
+            Partial_Reveal_Object *refobj = *ref;
+            offset_list++;
+
+            if (!refobj) continue;
+
+            if (mark_object(refobj)) {
+                objects.push_back(refobj);
+            } else if (is_forwarded_object(refobj)) {
+                update_forwarded_reference(refobj, ref);
+                continue;
+            }
+
+            if (is_compaction_object(refobj)) {
+                if (is_left_object(refobj, ref)) {
+                    enqueue_reference(refobj, ref);
+                } else {
+                    // mark_rescan_reference
+                    *ref = (Partial_Reveal_Object*) ((size_t)refobj | 1);
+                    rescan = true;
+                }
+            }
+        }
+        if (rescan) set_rescan_bit(obj);
+    } else {
+        int offset;
+        while ((offset = *offset_list) != 0) {
+            Partial_Reveal_Object **ref = (Partial_Reveal_Object**)((char*)obj + offset);
+            Partial_Reveal_Object *refobj = *ref;
+            offset_list++;
+
+            if (!refobj) continue;
+
+            if (mark_object(refobj)) {
+                objects.push_back(refobj);
+            } else if (is_forwarded_object(refobj)) {
+                update_forwarded_reference(refobj, ref);
+                continue;
+            }
+
+            if (is_compaction_object(refobj)) {
+                enqueue_reference(refobj, ref);
+            }
+        }
+    }
+
+}
+
+static void gc_slide_add_root_set_entry_internal(Partial_Reveal_Object **ref, Boolean is_pinned) {
+    // get object
+    Partial_Reveal_Object *refobj = *ref;
+
+    // check no garbage
+    assert(((int)refobj & 3) == 0);
+
+    // empty references is not interesting
+    if (!refobj) return;
+    assert(!is_pinned); // no pinning allowed for now
+
+    if (mark_object(refobj)) {
+        // object wasn't marked yet
+        slide_process_object(refobj, is_pinned);
+    } else if (is_forwarded_object(refobj)) {
+        update_forwarded_reference(refobj, ref);
+        goto skip;
+    }
+
+    if (is_compaction_object(refobj)) {
+        enqueue_reference(refobj, ref);
+    }
+skip:
+
+    while (true) {
+        if (objects.empty()) break;
+        Partial_Reveal_Object *obj = objects.pop_back();
+        slide_process_object(obj, false);
+    }
+}
+
+void gc_slide_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned) {
+    //TRACE2("gc.enum", "gc_add_root_set_entry");
+    gc_slide_add_root_set_entry_internal((Partial_Reveal_Object**)ref, is_pinned);
+}
+
+void gc_slide_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned)
+{
+    InteriorPointer ip;
+    ip.obj = (Partial_Reveal_Object*) (*(unsigned char**)slot - offset);
+    ip.interior_ref = (Partial_Reveal_Object**)slot;
+    ip.offset = offset;
+    InteriorPointer& ips = comp_interior_pointers.push_back(ip);
+    gc_slide_add_root_set_entry_internal((Partial_Reveal_Object**)&ips.obj, is_pinned);
+}
+
+void gc_process_interior_pointers() {
+    fast_list<InteriorPointer,256>::iterator begin = comp_interior_pointers.begin();
+    fast_list<InteriorPointer,256>::iterator end = comp_interior_pointers.end();
+
+    for(fast_list<InteriorPointer,256>::iterator i = begin; i != end; ++i) {
+        *(*i).interior_ref = (Partial_Reveal_Object*)((unsigned char*)(*i).obj + (*i).offset);
+    }
+}
+
+void gc_slide_process_special_references(reference_vector& array) {
+    for(reference_vector::iterator i = array.begin();
+            i != array.end(); ++i) {
+        Partial_Reveal_Object *obj = *i;
+
+        Partial_Reveal_Object **ref = 
+            (Partial_Reveal_Object**) ((unsigned char *)obj + global_referent_offset);
+        Partial_Reveal_Object* refobj = *ref;
+
+        if (refobj == 0) {
+            // reference already cleared, no post processing needed
+            *i = 0;
+            continue;
+        }
+
+        if (is_object_marked(refobj)) {
+            //assert(mark_bit_is_set(refobj) || !is_compaction_object(refobj) || is_forwarded_object(refobj));
+
+            if (is_forwarded_object(refobj)) {
+                update_forwarded_reference(refobj, ref);
+            } else if (is_compaction_object(refobj)) {
+                if (is_left_object(refobj, ref) || !is_compaction_object(obj)) {
+                    enqueue_reference(refobj, ref);
+                } else {
+                    // mark_rescan_reference
+                    *ref = (Partial_Reveal_Object*) ((size_t)refobj | 1);
+                    set_rescan_bit(obj);
+                }
+            }
+
+            // no post processing needed
+            *i = 0;
+            continue;
+        } else {
+            //assert(!mark_bit_is_set(refobj));
+        }
+
+        // object not marked, clear reference
+        *ref = (Partial_Reveal_Object*)0;
+
+        if (is_forwarded_object(obj)) {
+            update_forwarded_reference(obj, &*i);
+        } else if (is_compaction_object(obj)) {
+            enqueue_reference(obj, &*i);
+        }
+    }
+}
+
+void gc_slide_postprocess_special_references(reference_vector& array) {
+    for(reference_vector::iterator i = array.begin();
+            i != array.end(); ++i) {
+        Partial_Reveal_Object *obj = *i;
+
+        if (!obj) continue;
+        vm_enqueue_reference((Managed_Object_Handle*)obj);
+    }
+}
+
+// transition from coping collector code
+// all previous references are processed in copying collector
+// so will not move, they can be considered as root references here
+
+void gc_slide_process_transitional_slots(fast_list<Partial_Reveal_Object**,65536>& slots) {
+    // also process pinned objects all but last
+    pinned_areas_unsorted_t::iterator end = --(--pinned_areas_unsorted.end());
+    for(pinned_areas_unsorted_t::iterator i = pinned_areas_unsorted.begin();
+            i != end; ++i,++i) {
+        Partial_Reveal_Object *obj = (Partial_Reveal_Object*) *i;
+        if (is_compaction_object(obj)) {
+            set_mark_bit(obj);
+            obj->obj_info() |= MARK_BITS;
+        }
+    }
+
+    while (true) {
+        if (slots.empty()) break;
+        Partial_Reveal_Object **ref = slots.pop_back();
+        gc_slide_add_root_set_entry_internal(ref, false);
+    }
+}
+void gc_slide_process_transitional_slots(Partial_Reveal_Object **refs, int pos, int length) {
+    for(int i = pos; i < length; i++) {
+        Partial_Reveal_Object **ref = &refs[i];
+        gc_slide_add_root_set_entry_internal(ref, false);
+    }
+}

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/gc/src/collect_slide_compact.cpp
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message