Reviewers: Jakob,

Message:
PTAL.

Description:
CNLT with descriptors but no valid enum fields has to clear the EnumCache.


Please review this at https://chromiumcodereview.appspot.com/10928204/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/objects.h
  M src/objects.cc
  A + test/mjsunit/regress/regress-cntl-descriptors-enum.js


Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 3c193a5271502e38bf00ec129b961d1ef662df2c..9f1bd09d278e58735bf59842753db6a46549e52a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -6088,6 +6088,11 @@ MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) {
 }


+void DescriptorArray::ClearEnumCache() {
+  set(kEnumCacheIndex, Smi::FromInt(0));
+}
+
+
 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
                                    FixedArray* new_cache,
                                    Object* new_index_cache) {
@@ -7489,19 +7494,24 @@ void Map::ClearNonLiveTransitions(Heap* heap) {

   if (descriptors_owner_died) {
     if (number_of_own_descriptors > 0) {
- int live_enum = NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
       int number_of_descriptors = descriptors->number_of_descriptors();
       int to_trim = number_of_descriptors - number_of_own_descriptors;
       if (to_trim > 0) {
         RightTrimFixedArray<FROM_GC>(
             heap, descriptors, to_trim * DescriptorArray::kDescriptorSize);
         if (descriptors->HasEnumCache()) {
-          FixedArray* enum_cache =
-              FixedArray::cast(descriptors->GetEnumCache());
-          to_trim = enum_cache->length() - live_enum;
-          if (to_trim > 0) {
-            RightTrimFixedArray<FROM_GC>(
- heap, FixedArray::cast(descriptors->GetEnumCache()), to_trim);
+          int live_enum =
+              NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
+          if (live_enum == 0) {
+            descriptors->ClearEnumCache();
+          } else {
+            FixedArray* enum_cache =
+                FixedArray::cast(descriptors->GetEnumCache());
+            to_trim = enum_cache->length() - live_enum;
+            if (to_trim > 0) {
+              RightTrimFixedArray<FROM_GC>(
+ heap, FixedArray::cast(descriptors->GetEnumCache()), to_trim);
+            }
           }
         }
         descriptors->Sort();
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index e1f1d3bad4df0aaf18bb5379caaf1a5c655d5f5f..51d6c37057aeb72f1feeb5366f5ea2b0bdd9af6b 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2509,6 +2509,8 @@ class DescriptorArray: public FixedArray {
                                 kEnumCacheOffset);
   }

+  void ClearEnumCache();
+
   // Initialize or change the enum cache,
   // using the supplied storage for the small "bridge".
   void SetEnumCache(FixedArray* bridge_storage,
Index: test/mjsunit/regress/regress-cntl-descriptors-enum.js
diff --git a/test/mjsunit/regress/regress-2249.js b/test/mjsunit/regress/regress-cntl-descriptors-enum.js
similarity index 85%
copy from test/mjsunit/regress/regress-2249.js
copy to test/mjsunit/regress/regress-cntl-descriptors-enum.js
index 07d687d8191ad469d09cbd86cd7ea12797a735d3..ee72fafc8a7c67f2b1ab6cc22a734ef8033a5697 100644
--- a/test/mjsunit/regress/regress-2249.js
+++ b/test/mjsunit/regress/regress-cntl-descriptors-enum.js
@@ -25,9 +25,22 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Flags: --gc-interval=10 --stress-compaction
+// Flags: --allow-natives-syntax --expose-gc
+
+DontEnum = 2;

 var o = {};
-o[Math.pow(2,30)-1] = 0;
-o[Math.pow(2,31)-1] = 0;
-o[1] = 0;
+%SetProperty(o, "a", 0, DontEnum);
+
+var o2 = {};
+%SetProperty(o2, "a", 0, DontEnum);
+
+assertTrue(%HaveSameMap(o, o2));
+
+o.y = 2;
+
+for (var v in o) { print(v); }
+o = {};
+gc();
+
+for (var v in o2) { print(v); }


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to