diff --git a/src/objects.cc b/src/objects.cc index 3c193a5271..9f1bd09d27 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( 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( - 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( + heap, FixedArray::cast(descriptors->GetEnumCache()), to_trim); + } } } descriptors->Sort(); diff --git a/src/objects.h b/src/objects.h index e1f1d3bad4..51d6c37057 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, diff --git a/test/mjsunit/regress/regress-cntl-descriptors-enum.js b/test/mjsunit/regress/regress-cntl-descriptors-enum.js new file mode 100644 index 0000000000..ee72fafc8a --- /dev/null +++ b/test/mjsunit/regress/regress-cntl-descriptors-enum.js @@ -0,0 +1,46 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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: --allow-natives-syntax --expose-gc + +DontEnum = 2; + +var o = {}; +%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); }