Revert "ES6: Add support for Map/Set forEach"
authoradamk@chromium.org <adamk@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 16 Apr 2014 21:19:25 +0000 (21:19 +0000)
committeradamk@chromium.org <adamk@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 16 Apr 2014 21:19:25 +0000 (21:19 +0000)
This reverts https://code.google.com/p/v8/source/detail?r=20823

It broke Windows builds. Will need to find a Windows try bot to figure
out why.

TBR=mstarzinger@chromium.org,arv@chromium.org

Review URL: https://codereview.chromium.org/238973011

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20824 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

22 files changed:
src/arm/full-codegen-arm.cc
src/arm64/full-codegen-arm64.cc
src/array-iterator.js
src/bootstrapper.cc
src/collection.js
src/contexts.h
src/factory.cc
src/factory.h
src/ia32/full-codegen-ia32.cc
src/macros.py
src/mips/full-codegen-mips.cc
src/objects-debug.cc
src/objects-inl.h
src/objects-printer.cc
src/objects-visiting.cc
src/objects.cc
src/objects.h
src/runtime.cc
src/runtime.h
src/x64/full-codegen-x64.cc
test/cctest/test-ordered-hash-table.cc
test/mjsunit/harmony/collections.js

index 3679a6f..92664ed 100644 (file)
@@ -2278,7 +2278,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
   Label gc_required;
   Label allocated;
 
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
+  Handle<Map> map(isolate()->native_context()->generator_result_map());
 
   __ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT);
   __ jmp(&allocated);
index 76bb1b5..96e6d65 100644 (file)
@@ -4706,7 +4706,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
   Label gc_required;
   Label allocated;
 
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
+  Handle<Map> map(isolate()->native_context()->generator_result_map());
 
   // Allocate and populate an object with this form: { value: VAL, done: DONE }
 
index 10116b1..3af659d 100644 (file)
 // in runtime.js:
 // var $Array = global.Array;
 
+var ARRAY_ITERATOR_KIND_KEYS = 1;
+var ARRAY_ITERATOR_KIND_VALUES = 2;
+var ARRAY_ITERATOR_KIND_ENTRIES = 3;
+// The spec draft also has "sparse" but it is never used.
+
 var arrayIteratorObjectSymbol = GLOBAL_PRIVATE("ArrayIterator#object");
 var arrayIteratorNextIndexSymbol = GLOBAL_PRIVATE("ArrayIterator#next");
 var arrayIterationKindSymbol = GLOBAL_PRIVATE("ArrayIterator#kind");
@@ -74,25 +79,25 @@ function ArrayIteratorNext() {
 
   SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, index + 1);
 
-  if (itemKind == ITERATOR_KIND_VALUES)
+  if (itemKind == ARRAY_ITERATOR_KIND_VALUES)
     return CreateIteratorResultObject(array[index], false);
 
-  if (itemKind == ITERATOR_KIND_ENTRIES)
+  if (itemKind == ARRAY_ITERATOR_KIND_ENTRIES)
     return CreateIteratorResultObject([index, array[index]], false);
 
   return CreateIteratorResultObject(index, false);
 }
 
 function ArrayEntries() {
-  return CreateArrayIterator(this, ITERATOR_KIND_ENTRIES);
+  return CreateArrayIterator(this, ARRAY_ITERATOR_KIND_ENTRIES);
 }
 
 function ArrayValues() {
-  return CreateArrayIterator(this, ITERATOR_KIND_VALUES);
+  return CreateArrayIterator(this, ARRAY_ITERATOR_KIND_VALUES);
 }
 
 function ArrayKeys() {
-  return CreateArrayIterator(this, ITERATOR_KIND_KEYS);
+  return CreateArrayIterator(this, ARRAY_ITERATOR_KIND_KEYS);
 }
 
 function SetUpArrayIterator() {
index 4f0c0fe..351d14a 100644 (file)
@@ -1304,16 +1304,6 @@ void Genesis::InitializeExperimentalGlobal() {
                       isolate()->initial_object_prototype(),
                       Builtins::kIllegal, true, true);
     }
-    {   // -- S e t I t e r a t o r
-      Handle<Map> map = isolate()->factory()->NewMap(
-          JS_SET_ITERATOR_TYPE, JSSetIterator::kSize);
-      native_context()->set_set_iterator_map(*map);
-    }
-    {   // -- M a p I t e r a t o r
-      Handle<Map> map = isolate()->factory()->NewMap(
-          JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize);
-      native_context()->set_map_iterator_map(*map);
-    }
   }
 
   if (FLAG_harmony_weak_collections) {
@@ -1368,38 +1358,37 @@ void Genesis::InitializeExperimentalGlobal() {
         *generator_object_prototype);
     native_context()->set_generator_object_prototype_map(
         *generator_object_prototype_map);
-  }
-
-  if (FLAG_harmony_collections || FLAG_harmony_generators) {
-    // Collection forEach uses an iterator result object.
-    // Generators return iteraror result objects.
 
-    STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2);
-    Handle<JSFunction> object_function(native_context()->object_function());
+    // Create a map for generator result objects.
     ASSERT(object_function->initial_map()->inobject_properties() == 0);
-    Handle<Map> iterator_result_map = Map::Create(
+    STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2);
+    Handle<Map> generator_result_map = Map::Create(
         object_function, JSGeneratorObject::kResultPropertyCount);
-    ASSERT(iterator_result_map->inobject_properties() ==
+    ASSERT(generator_result_map->inobject_properties() ==
         JSGeneratorObject::kResultPropertyCount);
     Map::EnsureDescriptorSlack(
-        iterator_result_map, JSGeneratorObject::kResultPropertyCount);
+        generator_result_map, JSGeneratorObject::kResultPropertyCount);
 
-    FieldDescriptor value_descr(isolate()->factory()->value_string(),
+    Handle<String> value_string = factory()->InternalizeOneByteString(
+        STATIC_ASCII_VECTOR("value"));
+    FieldDescriptor value_descr(value_string,
                                 JSGeneratorObject::kResultValuePropertyIndex,
                                 NONE,
                                 Representation::Tagged());
-    iterator_result_map->AppendDescriptor(&value_descr);
+    generator_result_map->AppendDescriptor(&value_descr);
 
-    FieldDescriptor done_descr(isolate()->factory()->done_string(),
+    Handle<String> done_string = factory()->InternalizeOneByteString(
+        STATIC_ASCII_VECTOR("done"));
+    FieldDescriptor done_descr(done_string,
                                JSGeneratorObject::kResultDonePropertyIndex,
                                NONE,
                                Representation::Tagged());
-    iterator_result_map->AppendDescriptor(&done_descr);
+    generator_result_map->AppendDescriptor(&done_descr);
 
-    iterator_result_map->set_unused_property_fields(0);
+    generator_result_map->set_unused_property_fields(0);
     ASSERT_EQ(JSGeneratorObject::kResultSize,
-              iterator_result_map->instance_size());
-    native_context()->set_iterator_result_map(*iterator_result_map);
+              generator_result_map->instance_size());
+    native_context()->set_generator_result_map(*generator_result_map);
   }
 }
 
index f2b481b..9054187 100644 (file)
@@ -113,29 +113,8 @@ function SetClear() {
     throw MakeTypeError('incompatible_method_receiver',
                         ['Set.prototype.clear', this]);
   }
-  %SetClear(this);
-}
-
-
-function SetForEach(f, receiver) {
-  if (!IS_SET(this)) {
-    throw MakeTypeError('incompatible_method_receiver',
-                        ['Set.prototype.forEach', this]);
-  }
-
-  if (!IS_SPEC_FUNCTION(f)) {
-    throw MakeTypeError('called_non_callable', [f]);
-  }
-
-  var iterator = %SetCreateIterator(this, ITERATOR_KIND_VALUES);
-  var entry;
-  try {
-    while (!(entry = %SetIteratorNext(iterator)).done) {
-      %_CallFunction(receiver, entry.value, entry.value, this, f);
-    }
-  } finally {
-    %SetIteratorClose(iterator);
-  }
+  // Replace the internal table with a new empty table.
+  %SetInitialize(this);
 }
 
 
@@ -148,16 +127,13 @@ function SetUpSet() {
   %FunctionSetPrototype($Set, new $Object());
   %SetProperty($Set.prototype, "constructor", $Set, DONT_ENUM);
 
-  %FunctionSetLength(SetForEach, 1);
-
   // Set up the non-enumerable functions on the Set prototype object.
   InstallGetter($Set.prototype, "size", SetGetSize);
   InstallFunctions($Set.prototype, DONT_ENUM, $Array(
     "add", SetAdd,
     "has", SetHas,
     "delete", SetDelete,
-    "clear", SetClear,
-    "forEach", SetForEach
+    "clear", SetClear
   ));
 }
 
@@ -226,29 +202,8 @@ function MapClear() {
     throw MakeTypeError('incompatible_method_receiver',
                         ['Map.prototype.clear', this]);
   }
-  %MapClear(this);
-}
-
-
-function MapForEach(f, receiver) {
-  if (!IS_MAP(this)) {
-    throw MakeTypeError('incompatible_method_receiver',
-                        ['Map.prototype.forEach', this]);
-  }
-
-  if (!IS_SPEC_FUNCTION(f)) {
-    throw MakeTypeError('called_non_callable', [f]);
-  }
-
-  var iterator = %MapCreateIterator(this, ITERATOR_KIND_ENTRIES);
-  var entry;
-  try {
-    while (!(entry = %MapIteratorNext(iterator)).done) {
-      %_CallFunction(receiver, entry.value[1], entry.value[0], this, f);
-    }
-  } finally {
-    %MapIteratorClose(iterator);
-  }
+  // Replace the internal table with a new empty table.
+  %MapInitialize(this);
 }
 
 
@@ -261,8 +216,6 @@ function SetUpMap() {
   %FunctionSetPrototype($Map, new $Object());
   %SetProperty($Map.prototype, "constructor", $Map, DONT_ENUM);
 
-  %FunctionSetLength(MapForEach, 1);
-
   // Set up the non-enumerable functions on the Map prototype object.
   InstallGetter($Map.prototype, "size", MapGetSize);
   InstallFunctions($Map.prototype, DONT_ENUM, $Array(
@@ -270,8 +223,7 @@ function SetUpMap() {
     "set", MapSet,
     "has", MapHas,
     "delete", MapDelete,
-    "clear", MapClear,
-    "forEach", MapForEach
+    "clear", MapClear
   ));
 }
 
index 7bb6eb4..6ba9b3e 100644 (file)
@@ -191,9 +191,7 @@ enum BindingFlags {
   V(STRICT_GENERATOR_FUNCTION_MAP_INDEX, Map, strict_generator_function_map) \
   V(GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX, Map, \
     generator_object_prototype_map) \
-  V(ITERATOR_RESULT_MAP_INDEX, Map, iterator_result_map) \
-  V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map) \
-  V(SET_ITERATOR_MAP_INDEX, Map, set_iterator_map)
+  V(GENERATOR_RESULT_MAP_INDEX, Map, generator_result_map)
 
 // JSFunctions are pairs (context, function code), sometimes also called
 // closures. A Context object is used to represent function contexts and
@@ -349,9 +347,7 @@ class Context: public FixedArray {
     SLOPPY_GENERATOR_FUNCTION_MAP_INDEX,
     STRICT_GENERATOR_FUNCTION_MAP_INDEX,
     GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX,
-    ITERATOR_RESULT_MAP_INDEX,
-    MAP_ITERATOR_MAP_INDEX,
-    SET_ITERATOR_MAP_INDEX,
+    GENERATOR_RESULT_MAP_INDEX,
 
     // Properties from here are treated as weak references by the full GC.
     // Scavenge treats them as strong references.
index 23ecafd..9bcbf01 100644 (file)
@@ -1330,18 +1330,6 @@ Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
 }
 
 
-Handle<JSObject> Factory::NewIteratorResultObject(Handle<Object> value,
-                                                     bool done) {
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
-  Handle<JSObject> result = NewJSObjectFromMap(map, NOT_TENURED, false);
-  result->InObjectPropertyAtPut(
-      JSGeneratorObject::kResultValuePropertyIndex, *value);
-  result->InObjectPropertyAtPut(
-      JSGeneratorObject::kResultDonePropertyIndex, *ToBoolean(done));
-  return result;
-}
-
-
 Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
   Handle<FixedArray> array = NewFixedArray(length, TENURED);
   array->set_map_no_write_barrier(*scope_info_map());
@@ -2349,5 +2337,4 @@ Handle<Object> Factory::ToBoolean(bool value) {
   return value ? true_value() : false_value();
 }
 
-
 } }  // namespace v8::internal
index 8567ff3..d52e66e 100644 (file)
@@ -504,8 +504,6 @@ class Factory V8_FINAL {
   Handle<Object> NewEvalError(const char* message,
                               Vector< Handle<Object> > args);
 
-  Handle<JSObject> NewIteratorResultObject(Handle<Object> value, bool done);
-
   Handle<String> NumberToString(Handle<Object> number,
                                 bool check_number_string_cache = true);
 
index fbd9a21..3eacdd5 100644 (file)
@@ -2227,7 +2227,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
   Label gc_required;
   Label allocated;
 
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
+  Handle<Map> map(isolate()->native_context()->generator_result_map());
 
   __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT);
   __ jmp(&allocated);
index 2a7dbdd..0b69e6b 100644 (file)
@@ -272,8 +272,3 @@ const PROPERTY_ATTRIBUTES_NONE = 0;
 const PROPERTY_ATTRIBUTES_STRING = 8;
 const PROPERTY_ATTRIBUTES_SYMBOLIC = 16;
 const PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL = 32;
-
-# Use for keys, values and entries iterators.
-const ITERATOR_KIND_KEYS = 1;
-const ITERATOR_KIND_VALUES = 2;
-const ITERATOR_KIND_ENTRIES = 3;
index 1466af6..ef6bc84 100644 (file)
@@ -2285,7 +2285,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
   Label gc_required;
   Label allocated;
 
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
+  Handle<Map> map(isolate()->native_context()->generator_result_map());
 
   __ Allocate(map->instance_size(), v0, a2, a3, &gc_required, TAG_OBJECT);
   __ jmp(&allocated);
index d21e65e..40132cb 100644 (file)
@@ -170,12 +170,6 @@ void HeapObject::HeapObjectVerify() {
     case JS_MAP_TYPE:
       JSMap::cast(this)->JSMapVerify();
       break;
-    case JS_SET_ITERATOR_TYPE:
-      JSSetIterator::cast(this)->JSSetIteratorVerify();
-      break;
-    case JS_MAP_ITERATOR_TYPE:
-      JSMapIterator::cast(this)->JSMapIteratorVerify();
-      break;
     case JS_WEAK_MAP_TYPE:
       JSWeakMap::cast(this)->JSWeakMapVerify();
       break;
@@ -717,7 +711,6 @@ void JSSet::JSSetVerify() {
   JSObjectVerify();
   VerifyHeapPointer(table());
   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
-  // TODO(arv): Verify OrderedHashTable too.
 }
 
 
@@ -726,39 +719,6 @@ void JSMap::JSMapVerify() {
   JSObjectVerify();
   VerifyHeapPointer(table());
   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
-  // TODO(arv): Verify OrderedHashTable too.
-}
-
-
-void JSSetIterator::JSSetIteratorVerify() {
-  CHECK(IsJSSetIterator());
-  JSObjectVerify();
-  VerifyHeapPointer(table());
-  CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
-  CHECK(index()->IsSmi());
-  CHECK(count()->IsSmi());
-  CHECK(kind()->IsSmi());
-  VerifyHeapPointer(next_iterator());
-  CHECK(next_iterator()->IsJSSetIterator() || next_iterator()->IsUndefined());
-  VerifyHeapPointer(table());
-  CHECK(previous_iterator()->IsJSSetIterator()
-        || previous_iterator()->IsUndefined());
-}
-
-
-void JSMapIterator::JSMapIteratorVerify() {
-  CHECK(IsJSMapIterator());
-  JSObjectVerify();
-  VerifyHeapPointer(table());
-  CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
-  CHECK(index()->IsSmi());
-  CHECK(count()->IsSmi());
-  CHECK(kind()->IsSmi());
-  VerifyHeapPointer(next_iterator());
-  CHECK(next_iterator()->IsJSMapIterator() || next_iterator()->IsUndefined());
-  VerifyHeapPointer(table());
-  CHECK(previous_iterator()->IsJSMapIterator()
-        || previous_iterator()->IsUndefined());
 }
 
 
index a89109f..023caa5 100644 (file)
@@ -696,8 +696,6 @@ bool Object::IsJSProxy() {
 TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
 TYPE_CHECKER(JSSet, JS_SET_TYPE)
 TYPE_CHECKER(JSMap, JS_MAP_TYPE)
-TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
-TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE)
 TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
 TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE)
 TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
@@ -1918,10 +1916,6 @@ int JSObject::GetHeaderSize() {
       return JSSet::kSize;
     case JS_MAP_TYPE:
       return JSMap::kSize;
-    case JS_SET_ITERATOR_TYPE:
-      return JSSetIterator::kSize;
-    case JS_MAP_ITERATOR_TYPE:
-      return JSMapIterator::kSize;
     case JS_WEAK_MAP_TYPE:
       return JSWeakMap::kSize;
     case JS_WEAK_SET_TYPE:
@@ -2982,8 +2976,6 @@ CAST_ACCESSOR(JSProxy)
 CAST_ACCESSOR(JSFunctionProxy)
 CAST_ACCESSOR(JSSet)
 CAST_ACCESSOR(JSMap)
-CAST_ACCESSOR(JSSetIterator)
-CAST_ACCESSOR(JSMapIterator)
 CAST_ACCESSOR(JSWeakMap)
 CAST_ACCESSOR(JSWeakSet)
 CAST_ACCESSOR(Foreign)
@@ -5815,32 +5807,6 @@ void JSProxy::InitializeBody(int object_size, Object* value) {
 
 ACCESSORS(JSSet, table, Object, kTableOffset)
 ACCESSORS(JSMap, table, Object, kTableOffset)
-
-
-#define ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(name, type, offset)    \
-  template<class Derived, class TableType>                           \
-  type* OrderedHashTableIterator<Derived, TableType>::name() {       \
-    return type::cast(READ_FIELD(this, offset));                     \
-  }                                                                  \
-  template<class Derived, class TableType>                           \
-  void OrderedHashTableIterator<Derived, TableType>::set_##name(     \
-      type* value, WriteBarrierMode mode) {                          \
-    WRITE_FIELD(this, offset, value);                                \
-    CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
-  }
-
-ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(table, Object, kTableOffset)
-ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(index, Smi, kIndexOffset)
-ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(count, Smi, kCountOffset)
-ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(kind, Smi, kKindOffset)
-ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(next_iterator, Object,
-                                      kNextIteratorOffset)
-ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(previous_iterator, Object,
-                                      kPreviousIteratorOffset)
-
-#undef ORDERED_HASH_TABLE_ITERATOR_ACCESSORS
-
-
 ACCESSORS(JSWeakCollection, table, Object, kTableOffset)
 ACCESSORS(JSWeakCollection, next, Object, kNextOffset)
 
@@ -6280,20 +6246,6 @@ SeededNumberDictionary* JSObject::element_dictionary() {
 }
 
 
-Handle<JSSetIterator> JSSetIterator::Create(
-    Handle<OrderedHashSet> table,
-    int kind) {
-  return CreateInternal(table->GetIsolate()->set_iterator_map(), table, kind);
-}
-
-
-Handle<JSMapIterator> JSMapIterator::Create(
-    Handle<OrderedHashMap> table,
-    int kind) {
-  return CreateInternal(table->GetIsolate()->map_iterator_map(), table, kind);
-}
-
-
 bool Name::IsHashFieldComputed(uint32_t field) {
   return (field & kHashNotComputedMask) == 0;
 }
index ea57b1a..a59b1e9 100644 (file)
@@ -174,12 +174,6 @@ void HeapObject::HeapObjectPrint(FILE* out) {
     case JS_MAP_TYPE:
       JSMap::cast(this)->JSMapPrint(out);
       break;
-    case JS_SET_ITERATOR_TYPE:
-      JSSetIterator::cast(this)->JSSetIteratorPrint(out);
-      break;
-    case JS_MAP_ITERATOR_TYPE:
-      JSMapIterator::cast(this)->JSMapIteratorPrint(out);
-      break;
     case JS_WEAK_MAP_TYPE:
       JSWeakMap::cast(this)->JSWeakMapPrint(out);
       break;
@@ -728,7 +722,7 @@ void JSProxy::JSProxyPrint(FILE* out) {
   PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
   PrintF(out, " - handler = ");
   handler()->Print(out);
-  PrintF(out, "\n - hash = ");
+  PrintF(out, " - hash = ");
   hash()->Print(out);
   PrintF(out, "\n");
 }
@@ -739,9 +733,9 @@ void JSFunctionProxy::JSFunctionProxyPrint(FILE* out) {
   PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
   PrintF(out, " - handler = ");
   handler()->Print(out);
-  PrintF(out, "\n - call_trap = ");
+  PrintF(out, " - call_trap = ");
   call_trap()->Print(out);
-  PrintF(out, "\n - construct_trap = ");
+  PrintF(out, " - construct_trap = ");
   construct_trap()->Print(out);
   PrintF(out, "\n");
 }
@@ -765,38 +759,6 @@ void JSMap::JSMapPrint(FILE* out) {
 }
 
 
-template<class Derived, class TableType>
-void OrderedHashTableIterator<Derived, TableType>::
-    OrderedHashTableIteratorPrint(FILE* out) {
-  PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
-  PrintF(out, " - table = ");
-  table()->ShortPrint(out);
-  PrintF(out, "\n - index = ");
-  index()->ShortPrint(out);
-  PrintF(out, "\n - count = ");
-  count()->ShortPrint(out);
-  PrintF(out, "\n - kind = ");
-  kind()->ShortPrint(out);
-  PrintF(out, "\n - next_iterator = ");
-  next_iterator()->ShortPrint(out);
-  PrintF(out, "\n - previous_iterator = ");
-  previous_iterator()->ShortPrint(out);
-  PrintF(out, "\n");
-}
-
-
-void JSSetIterator::JSSetIteratorPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "JSSetIterator");
-  OrderedHashTableIteratorPrint(out);
-}
-
-
-void JSMapIterator::JSMapIteratorPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "JSMapIterator");
-  OrderedHashTableIteratorPrint(out);
-}
-
-
 void JSWeakMap::JSWeakMapPrint(FILE* out) {
   HeapObject::PrintHeader(out, "JSWeakMap");
   PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
index 89de85c..b314a47 100644 (file)
@@ -163,8 +163,6 @@ StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId(
     case JS_GLOBAL_OBJECT_TYPE:
     case JS_BUILTINS_OBJECT_TYPE:
     case JS_MESSAGE_OBJECT_TYPE:
-    case JS_SET_ITERATOR_TYPE:
-    case JS_MAP_ITERATOR_TYPE:
       return GetVisitorIdForSize(kVisitJSObject,
                                  kVisitJSObjectGeneric,
                                  instance_size);
index ec96be9..4a3b542 100644 (file)
@@ -1675,8 +1675,6 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
     case JS_DATA_VIEW_TYPE:
     case JS_SET_TYPE:
     case JS_MAP_TYPE:
-    case JS_SET_ITERATOR_TYPE:
-    case JS_MAP_ITERATOR_TYPE:
     case JS_WEAK_MAP_TYPE:
     case JS_WEAK_SET_TYPE:
     case JS_REGEXP_TYPE:
@@ -16336,14 +16334,15 @@ void WeakHashTable::AddEntry(int entry, Object* key, Object* value) {
 }
 
 
-template<class Derived, class Iterator, int entrysize>
-Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate(
+template<class Derived, int entrysize>
+Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate(
     Isolate* isolate, int capacity, PretenureFlag pretenure) {
   // Capacity must be a power of two, since we depend on being able
   // to divide and multiple by 2 (kLoadFactor) to derive capacity
   // from number of buckets. If we decide to change kLoadFactor
   // to something other than 2, capacity should be stored as another
   // field of this object.
+  const int kMinCapacity = 4;
   capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity));
   if (capacity > kMaxCapacity) {
     v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
@@ -16360,13 +16359,12 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate(
   table->SetNumberOfBuckets(num_buckets);
   table->SetNumberOfElements(0);
   table->SetNumberOfDeletedElements(0);
-  table->set_iterators(isolate->heap()->undefined_value());
   return table;
 }
 
 
-template<class Derived, class Iterator, int entrysize>
-Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable(
+template<class Derived, int entrysize>
+Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable(
     Handle<Derived> table) {
   int nof = table->NumberOfElements();
   int nod = table->NumberOfDeletedElements();
@@ -16379,8 +16377,8 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable(
 }
 
 
-template<class Derived, class Iterator, int entrysize>
-Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink(
+template<class Derived, int entrysize>
+Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink(
     Handle<Derived> table) {
   int nof = table->NumberOfElements();
   int capacity = table->Capacity();
@@ -16389,31 +16387,8 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink(
 }
 
 
-template<class Derived, class Iterator, int entrysize>
-Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear(
-    Handle<Derived> table) {
-  Handle<Derived> new_table =
-      Allocate(table->GetIsolate(),
-               kMinCapacity,
-               table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
-
-  new_table->set_iterators(table->iterators());
-  table->set_iterators(table->GetHeap()->undefined_value());
-
-  DisallowHeapAllocation no_allocation;
-  for (Object* object = new_table->iterators();
-       !object->IsUndefined();
-       object = Iterator::cast(object)->next_iterator()) {
-    Iterator::cast(object)->TableCleared();
-    Iterator::cast(object)->set_table(*new_table);
-  }
-
-  return new_table;
-}
-
-
-template<class Derived, class Iterator, int entrysize>
-Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
+template<class Derived, int entrysize>
+Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
     Handle<Derived> table, int new_capacity) {
   Handle<Derived> new_table =
       Allocate(table->GetIsolate(),
@@ -16440,24 +16415,12 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
     ++new_entry;
   }
   new_table->SetNumberOfElements(nof);
-
-  new_table->set_iterators(table->iterators());
-  table->set_iterators(table->GetHeap()->undefined_value());
-
-  DisallowHeapAllocation no_allocation;
-  for (Object* object = new_table->iterators();
-       !object->IsUndefined();
-       object = Iterator::cast(object)->next_iterator()) {
-    Iterator::cast(object)->TableCompacted();
-    Iterator::cast(object)->set_table(*new_table);
-  }
-
   return new_table;
 }
 
 
-template<class Derived, class Iterator, int entrysize>
-int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry(Object* key) {
+template<class Derived, int entrysize>
+int OrderedHashTable<Derived, entrysize>::FindEntry(Object* key) {
   ASSERT(!key->IsTheHole());
   Object* hash = key->GetHash();
   if (hash->IsUndefined()) return kNotFound;
@@ -16472,9 +16435,9 @@ int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry(Object* key) {
 }
 
 
-template<class Derived, class Iterator, int entrysize>
-int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) {
-  int entry = UsedCapacity();
+template<class Derived, int entrysize>
+int OrderedHashTable<Derived, entrysize>::AddEntry(int hash) {
+  int entry = NumberOfElements() + NumberOfDeletedElements();
   int bucket = HashToBucket(hash);
   int index = EntryToIndex(entry);
   Object* chain_entry = get(kHashTableStartIndex + bucket);
@@ -16485,32 +16448,19 @@ int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) {
 }
 
 
-template<class Derived, class Iterator, int entrysize>
-void OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) {
+template<class Derived, int entrysize>
+void OrderedHashTable<Derived, entrysize>::RemoveEntry(int entry) {
   int index = EntryToIndex(entry);
   for (int i = 0; i < entrysize; ++i) {
     set_the_hole(index + i);
   }
   SetNumberOfElements(NumberOfElements() - 1);
   SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
-
-  DisallowHeapAllocation no_allocation;
-  for (Object* object = iterators();
-       !object->IsUndefined();
-       object = Iterator::cast(object)->next_iterator()) {
-    Iterator::cast(object)->EntryRemoved(entry);
-  }
 }
 
 
-template int OrderedHashTable<OrderedHashSet, JSSetIterator,
-    1>::FindEntry(Object* key);
-template int OrderedHashTable<OrderedHashMap, JSMapIterator,
-    2>::FindEntry(Object* key);
-
-
-template class OrderedHashTable<OrderedHashSet, JSSetIterator, 1>;
-template class OrderedHashTable<OrderedHashMap, JSMapIterator, 2>;
+template class OrderedHashTable<OrderedHashSet, 1>;
+template class OrderedHashTable<OrderedHashMap, 2>;
 
 
 bool OrderedHashSet::Contains(Object* key) {
@@ -16536,6 +16486,7 @@ Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table,
   int entry = table->FindEntry(*key);
   if (entry == kNotFound) return table;
   table->RemoveEntry(entry);
+  // TODO(adamk): Don't shrink if we're being iterated over
   return Shrink(table);
 }
 
@@ -16555,6 +16506,7 @@ Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table,
   if (value->IsTheHole()) {
     if (entry == kNotFound) return table;
     table->RemoveEntry(entry);
+    // TODO(adamk): Only shrink if not iterating
     return Shrink(table);
   }
 
@@ -16573,199 +16525,6 @@ Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table,
 }
 
 
-template<class Derived, class TableType>
-void OrderedHashTableIterator<Derived, TableType>::EntryRemoved(int index) {
-  int i = this->index()->value();
-  if (index < i) {
-    set_count(Smi::FromInt(count()->value() - 1));
-  }
-  if (index == i) {
-    Seek();
-  }
-}
-
-
-template<class Derived, class TableType>
-void OrderedHashTableIterator<Derived, TableType>::Close() {
-  if (Closed()) return;
-
-  DisallowHeapAllocation no_allocation;
-
-  Object* undefined = GetHeap()->undefined_value();
-  TableType* table = TableType::cast(this->table());
-  Object* previous = previous_iterator();
-  Object* next = next_iterator();
-
-  if (previous == undefined) {
-    ASSERT_EQ(table->iterators(), this);
-    table->set_iterators(next);
-  } else {
-    ASSERT_EQ(Derived::cast(previous)->next_iterator(), this);
-    Derived::cast(previous)->set_next_iterator(next);
-  }
-
-  if (!next->IsUndefined()) {
-    ASSERT_EQ(Derived::cast(next)->previous_iterator(), this);
-    Derived::cast(next)->set_previous_iterator(previous);
-  }
-
-  set_previous_iterator(undefined);
-  set_next_iterator(undefined);
-  set_table(undefined);
-}
-
-
-template<class Derived, class TableType>
-void OrderedHashTableIterator<Derived, TableType>::Seek() {
-  ASSERT(!Closed());
-
-  DisallowHeapAllocation no_allocation;
-
-  int index = this->index()->value();
-
-  TableType* table = TableType::cast(this->table());
-  int used_capacity = table->UsedCapacity();
-
-  while (index < used_capacity && table->KeyAt(index)->IsTheHole()) {
-    index++;
-  }
-  set_index(Smi::FromInt(index));
-}
-
-
-template<class Derived, class TableType>
-void OrderedHashTableIterator<Derived, TableType>::MoveNext() {
-  ASSERT(!Closed());
-
-  set_index(Smi::FromInt(index()->value() + 1));
-  set_count(Smi::FromInt(count()->value() + 1));
-  Seek();
-}
-
-
-template<class Derived, class TableType>
-Handle<JSObject> OrderedHashTableIterator<Derived, TableType>::Next(
-    Handle<Derived> iterator) {
-  Isolate* isolate = iterator->GetIsolate();
-  Factory* factory = isolate->factory();
-
-  Handle<Object> object(iterator->table(), isolate);
-
-  if (!object->IsUndefined()) {
-    Handle<TableType> table = Handle<TableType>::cast(object);
-    int index = iterator->index()->value();
-    if (index < table->UsedCapacity()) {
-      int entry_index = table->EntryToIndex(index);
-      iterator->MoveNext();
-      Handle<Object> value = Derived::ValueForKind(iterator, entry_index);
-      return factory->NewIteratorResultObject(value, false);
-    } else {
-      iterator->Close();
-    }
-  }
-
-  return factory->NewIteratorResultObject(factory->undefined_value(), true);
-}
-
-
-template<class Derived, class TableType>
-Handle<Derived> OrderedHashTableIterator<Derived, TableType>::CreateInternal(
-    Handle<Map> map,
-    Handle<TableType> table,
-    int kind) {
-  Isolate* isolate = table->GetIsolate();
-
-  Handle<Object> undefined = isolate->factory()->undefined_value();
-
-  Handle<Derived> new_iterator = Handle<Derived>::cast(
-      isolate->factory()->NewJSObjectFromMap(map));
-  new_iterator->set_previous_iterator(*undefined);
-  new_iterator->set_table(*table);
-  new_iterator->set_index(Smi::FromInt(0));
-  new_iterator->set_count(Smi::FromInt(0));
-  new_iterator->set_kind(Smi::FromInt(kind));
-
-  Handle<Object> old_iterator(table->iterators(), isolate);
-  if (!old_iterator->IsUndefined()) {
-    Handle<Derived>::cast(old_iterator)->set_previous_iterator(*new_iterator);
-    new_iterator->set_next_iterator(*old_iterator);
-  } else {
-    new_iterator->set_next_iterator(*undefined);
-  }
-
-  table->set_iterators(*new_iterator);
-
-  return new_iterator;
-}
-
-
-template Handle<JSObject> OrderedHashTableIterator<JSSetIterator,
-    OrderedHashSet>::Next(Handle<JSSetIterator> iterator);
-template Handle<JSObject> OrderedHashTableIterator<JSMapIterator,
-    OrderedHashMap>::Next(Handle<JSMapIterator> iterator);
-
-
-template class OrderedHashTableIterator<JSSetIterator, OrderedHashSet>;
-template class OrderedHashTableIterator<JSMapIterator, OrderedHashMap>;
-
-
-Handle<Object> JSSetIterator::ValueForKind(
-    Handle<JSSetIterator> iterator, int entry_index) {
-  int kind = iterator->kind()->value();
-  // Set.prototype only has values and entries.
-  ASSERT(kind == kKindValues || kind == kKindEntries);
-
-  Isolate* isolate = iterator->GetIsolate();
-  Factory* factory = isolate->factory();
-
-  Handle<OrderedHashSet> table(
-      OrderedHashSet::cast(iterator->table()), isolate);
-  Handle<Object> value = Handle<Object>(table->get(entry_index), isolate);
-
-  if (kind == kKindEntries) {
-    Handle<FixedArray> array = factory->NewFixedArray(2);
-    array->set(0, *value);
-    array->set(1, *value);
-    return factory->NewJSArrayWithElements(array);
-  }
-
-  return value;
-}
-
-
-Handle<Object> JSMapIterator::ValueForKind(
-    Handle<JSMapIterator> iterator, int entry_index) {
-  int kind = iterator->kind()->value();
-  ASSERT(kind == kKindKeys || kind == kKindValues || kind == kKindEntries);
-
-  Isolate* isolate = iterator->GetIsolate();
-  Factory* factory = isolate->factory();
-
-  Handle<OrderedHashMap> table(
-      OrderedHashMap::cast(iterator->table()), isolate);
-
-  switch (kind) {
-    case kKindKeys:
-      return Handle<Object>(table->get(entry_index), isolate);
-
-    case kKindValues:
-      return Handle<Object>(table->get(entry_index + 1), isolate);
-
-    case kKindEntries: {
-      Handle<Object> key(table->get(entry_index), isolate);
-      Handle<Object> value(table->get(entry_index + 1), isolate);
-      Handle<FixedArray> array = factory->NewFixedArray(2);
-      array->set(0, *key);
-      array->set(1, *value);
-      return factory->NewJSArrayWithElements(array);
-    }
-  }
-
-  UNREACHABLE();
-  return factory->undefined_value();
-}
-
-
 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator(
     DeclaredAccessorDescriptor* descriptor)
     : array_(descriptor->serialized_data()->GetDataStartAddress()),
index 58f1517..831e013 100644 (file)
@@ -66,8 +66,6 @@
 //             - JSDataView
 //           - JSSet
 //           - JSMap
-//           - JSSetIterator
-//           - JSMapIterator
 //           - JSWeakCollection
 //             - JSWeakMap
 //             - JSWeakSet
@@ -447,8 +445,6 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
   V(JS_PROXY_TYPE)                                                             \
   V(JS_SET_TYPE)                                                               \
   V(JS_MAP_TYPE)                                                               \
-  V(JS_SET_ITERATOR_TYPE)                                                      \
-  V(JS_MAP_ITERATOR_TYPE)                                                      \
   V(JS_WEAK_MAP_TYPE)                                                          \
   V(JS_WEAK_SET_TYPE)                                                          \
   V(JS_REGEXP_TYPE)                                                            \
@@ -797,8 +793,6 @@ enum InstanceType {
   JS_DATA_VIEW_TYPE,
   JS_SET_TYPE,
   JS_MAP_TYPE,
-  JS_SET_ITERATOR_TYPE,
-  JS_MAP_ITERATOR_TYPE,
   JS_WEAK_MAP_TYPE,
   JS_WEAK_SET_TYPE,
 
@@ -1046,8 +1040,6 @@ class MaybeObject BASE_EMBEDDED {
   V(JSFunctionProxy)                           \
   V(JSSet)                                     \
   V(JSMap)                                     \
-  V(JSSetIterator)                             \
-  V(JSMapIterator)                             \
   V(JSWeakCollection)                          \
   V(JSWeakMap)                                 \
   V(JSWeakSet)                                 \
@@ -4331,17 +4323,16 @@ class ObjectHashTable: public HashTable<ObjectHashTable,
 //   [0]: bucket count
 //   [1]: element count
 //   [2]: deleted element count
-//   [3]: live iterators (doubly-linked list)
-//   [4..(NumberOfBuckets() - 1)]: "hash table", where each item is an offset
+//   [3..(NumberOfBuckets() - 1)]: "hash table", where each item is an offset
 //                                 into the data table (see below) where the
 //                                 first item in this bucket is stored.
-//   [4 + NumberOfBuckets()..length]: "data table", an array of length
+//   [3 + NumberOfBuckets()..length]: "data table", an array of length
 //                            Capacity() * kEntrySize, where the first entrysize
 //                            items are handled by the derived class and the
 //                            item at kChainOffset is another entry into the
 //                            data table indicating the next entry in this hash
 //                            bucket.
-template<class Derived, class Iterator, int entrysize>
+template<class Derived, int entrysize>
 class OrderedHashTable: public FixedArray {
  public:
   // Returns an OrderedHashTable with a capacity of at least |capacity|.
@@ -4356,10 +4347,6 @@ class OrderedHashTable: public FixedArray {
   // if possible.
   static Handle<Derived> Shrink(Handle<Derived> table);
 
-  // Returns a new empty OrderedHashTable and updates all the iterators to
-  // point to the new table.
-  static Handle<Derived> Clear(Handle<Derived> table);
-
   // Returns kNotFound if the key isn't present.
   int FindEntry(Object* key);
 
@@ -4371,16 +4358,10 @@ class OrderedHashTable: public FixedArray {
     return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
   }
 
-  int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
-
   int NumberOfBuckets() {
     return Smi::cast(get(kNumberOfBucketsIndex))->value();
   }
 
-  Object* iterators() { return get(kIteratorsIndex); }
-
-  void set_iterators(Object* value) { set(kIteratorsIndex, value); }
-
   // Returns the index into the data table where the new entry
   // should be placed. The table is assumed to have enough space
   // for a new entry.
@@ -4395,10 +4376,7 @@ class OrderedHashTable: public FixedArray {
     return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
   }
 
-  Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
-
   static const int kNotFound = -1;
-  static const int kMinCapacity = 4;
 
  private:
   static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
@@ -4419,6 +4397,8 @@ class OrderedHashTable: public FixedArray {
     return NumberOfBuckets() * kLoadFactor;
   }
 
+  Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
+
   // Returns the next entry for the given entry.
   int ChainAt(int entry) {
     return Smi::cast(get(EntryToIndex(entry) + kChainOffset))->value();
@@ -4436,8 +4416,7 @@ class OrderedHashTable: public FixedArray {
   static const int kNumberOfBucketsIndex = 0;
   static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
   static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
-  static const int kIteratorsIndex = kNumberOfDeletedElementsIndex + 1;
-  static const int kHashTableStartIndex = kIteratorsIndex + 1;
+  static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
 
   static const int kEntrySize = entrysize + 1;
   static const int kChainOffset = entrysize;
@@ -4449,11 +4428,7 @@ class OrderedHashTable: public FixedArray {
 };
 
 
-class JSSetIterator;
-
-
-class OrderedHashSet: public OrderedHashTable<
-    OrderedHashSet, JSSetIterator, 1> {
+class OrderedHashSet: public OrderedHashTable<OrderedHashSet, 1> {
  public:
   static OrderedHashSet* cast(Object* obj) {
     ASSERT(obj->IsOrderedHashTable());
@@ -4468,11 +4443,7 @@ class OrderedHashSet: public OrderedHashTable<
 };
 
 
-class JSMapIterator;
-
-
-class OrderedHashMap:public OrderedHashTable<
-    OrderedHashMap, JSMapIterator, 2> {
+class OrderedHashMap: public OrderedHashTable<OrderedHashMap, 2> {
  public:
   static OrderedHashMap* cast(Object* obj) {
     ASSERT(obj->IsOrderedHashTable());
@@ -7627,7 +7598,7 @@ class JSGeneratorObject: public JSObject {
   enum ResumeMode { NEXT, THROW };
 
   // Yielding from a generator returns an object with the following inobject
-  // properties.  See Context::iterator_result_map() for the map.
+  // properties.  See Context::generator_result_map() for the map.
   static const int kResultValuePropertyIndex = 0;
   static const int kResultDonePropertyIndex = 1;
   static const int kResultPropertyCount = 2;
@@ -10106,149 +10077,6 @@ class JSMap: public JSObject {
 };
 
 
-// OrderedHashTableIterator is an iterator that iterates over the keys and
-// values of an OrderedHashTable.
-//
-// The hash table has a reference to the iterator and the iterators themselves
-// have references to the [next_iterator] and [previous_iterator], thus creating
-// a double linked list.
-//
-// When the hash table changes the iterators are called to update their [index]
-// and [count]. The hash table calls [EntryRemoved], [TableCompacted] as well
-// as [TableCleared].
-//
-// When an iterator is done it closes itself. It removes itself from the double
-// linked list and it sets its [table] to undefined, no longer keeping the
-// [table] alive.
-template<class Derived, class TableType>
-class OrderedHashTableIterator: public JSObject {
- public:
-  // [table]: the backing hash table mapping keys to values.
-  DECL_ACCESSORS(table, Object)
-
-  // [index]: The index into the data table.
-  DECL_ACCESSORS(index, Smi)
-
-  // [count]: The logical index into the data table, ignoring the holes.
-  DECL_ACCESSORS(count, Smi)
-
-  // [kind]: The kind of iteration this is. One of the [Kind] enum values.
-  DECL_ACCESSORS(kind, Smi)
-
-  // [next_iterator]: Used as a double linked list for the live iterators.
-  DECL_ACCESSORS(next_iterator, Object)
-
-  // [previous_iterator]: Used as a double linked list for the live iterators.
-  DECL_ACCESSORS(previous_iterator, Object)
-
-#ifdef OBJECT_PRINT
-  void OrderedHashTableIteratorPrint(FILE* out);
-#endif
-
-  static const int kTableOffset = JSObject::kHeaderSize;
-  static const int kIndexOffset = kTableOffset + kPointerSize;
-  static const int kCountOffset = kIndexOffset + kPointerSize;
-  static const int kKindOffset = kCountOffset + kPointerSize;
-  static const int kNextIteratorOffset = kKindOffset + kPointerSize;
-  static const int kPreviousIteratorOffset = kNextIteratorOffset + kPointerSize;
-  static const int kSize = kPreviousIteratorOffset + kPointerSize;
-
-  enum Kind {
-    kKindKeys = 1,
-    kKindValues = 2,
-    kKindEntries = 3
-  };
-
-  // Called by the underlying [table] when an entry is removed.
-  void EntryRemoved(int index);
-
-  // Called by the underlying [table] when it is compacted/rehashed.
-  void TableCompacted() {
-    // All holes have been removed so index is now same as count.
-    set_index(count());
-  }
-
-  // Called by the underlying [table] when it is cleared.
-  void TableCleared() {
-    set_index(Smi::FromInt(0));
-    set_count(Smi::FromInt(0));
-  }
-
-  // Removes the iterator from the double linked list and removes its reference
-  // back to the [table].
-  void Close();
-
-  // Returns an iterator result object: {value: any, done: boolean} and moves
-  // the index to the next valid entry. Closes the iterator if moving past the
-  // end.
-  static Handle<JSObject> Next(Handle<Derived> iterator);
-
- protected:
-  static Handle<Derived> CreateInternal(
-      Handle<Map> map, Handle<TableType> table, int kind);
-
- private:
-  // Ensures [index] is not pointing to a hole.
-  void Seek();
-
-  // Moves [index] to next valid entry. Closes the iterator if moving past the
-  // end.
-  void MoveNext();
-
-  bool Closed() {
-    return table()->IsUndefined();
-  }
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
-};
-
-
-class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
-                                                     OrderedHashSet> {
- public:
-  // Creates a new iterator associated with [table].
-  // [kind] needs to be one of the OrderedHashTableIterator Kind enum values.
-  static inline Handle<JSSetIterator> Create(
-      Handle<OrderedHashSet> table, int kind);
-
-  // Dispatched behavior.
-  DECLARE_PRINTER(JSSetIterator)
-  DECLARE_VERIFIER(JSSetIterator)
-
-  // Casting.
-  static inline JSSetIterator* cast(Object* obj);
-
-  static Handle<Object> ValueForKind(
-      Handle<JSSetIterator> iterator, int entry_index);
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
-};
-
-
-class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
-                                                     OrderedHashMap> {
- public:
-  // Creates a new iterator associated with [table].
-  // [kind] needs to be one of the OrderedHashTableIterator Kind enum values.
-  static inline Handle<JSMapIterator> Create(
-      Handle<OrderedHashMap> table, int kind);
-
-  // Dispatched behavior.
-  DECLARE_PRINTER(JSMapIterator)
-  DECLARE_VERIFIER(JSMapIterator)
-
-  // Casting.
-  static inline JSMapIterator* cast(Object* obj);
-
-  static Handle<Object> ValueForKind(
-      Handle<JSMapIterator> iterator, int entry_index);
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
-};
-
-
 // Base class for both JSWeakMap and JSWeakSet
 class JSWeakCollection: public JSObject {
  public:
index 0dde0d3..92dc782 100644 (file)
@@ -1552,17 +1552,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetClear) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  table = OrderedHashSet::Clear(table);
-  holder->set_table(*table);
-  return isolate->heap()->undefined_value();
-}
-
-
 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
@@ -1572,37 +1561,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) {
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCreateIterator) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  CONVERT_SMI_ARG_CHECKED(kind, 1)
-  ASSERT(kind == JSSetIterator::kKindValues
-      || kind == JSSetIterator::kKindEntries);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  Handle<JSSetIterator> iterator = JSSetIterator::Create(table, kind);
-  return *iterator;
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIteratorNext) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
-  Handle<JSObject> result = JSSetIterator::Next(holder);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIteratorClose) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
-  holder->Close();
-  return isolate->heap()->undefined_value();
-}
-
-
 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
@@ -1649,17 +1607,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapClear) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  table = OrderedHashMap::Clear(table);
-  holder->set_table(*table);
-  return isolate->heap()->undefined_value();
-}
-
-
 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 3);
@@ -1682,38 +1629,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) {
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapCreateIterator) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_SMI_ARG_CHECKED(kind, 1)
-  ASSERT(kind == JSMapIterator::kKindKeys
-      || kind == JSMapIterator::kKindValues
-      || kind == JSMapIterator::kKindEntries);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  Handle<JSMapIterator> iterator = JSMapIterator::Create(table, kind);
-  return *iterator;
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapIteratorNext) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
-  Handle<JSObject> result = JSMapIterator::Next(holder);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapIteratorClose) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
-  holder->Close();
-  return isolate->heap()->undefined_value();
-}
-
-
 static JSWeakCollection* WeakCollectionInitialize(Isolate* isolate,
     Handle<JSWeakCollection> weak_collection) {
   ASSERT(weak_collection->map()->inobject_properties() == 0);
index a32db2c..5b92b12 100644 (file)
@@ -297,25 +297,15 @@ namespace internal {
   F(SetAdd, 2, 1) \
   F(SetHas, 2, 1) \
   F(SetDelete, 2, 1) \
-  F(SetClear, 1, 1) \
   F(SetGetSize, 1, 1) \
-  F(SetCreateIterator, 2, 1) \
-  \
-  F(SetIteratorNext, 1, 1) \
-  F(SetIteratorClose, 1, 1) \
   \
   /* Harmony maps */ \
   F(MapInitialize, 1, 1) \
   F(MapGet, 2, 1) \
   F(MapHas, 2, 1) \
   F(MapDelete, 2, 1) \
-  F(MapClear, 1, 1) \
   F(MapSet, 3, 1) \
   F(MapGetSize, 1, 1) \
-  F(MapCreateIterator, 2, 1) \
-  \
-  F(MapIteratorNext, 1, 1) \
-  F(MapIteratorClose, 1, 1) \
   \
   /* Harmony weak maps and sets */ \
   F(WeakCollectionInitialize, 1, 1) \
index 44ffc29..c39ca97 100644 (file)
@@ -2264,7 +2264,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
   Label gc_required;
   Label allocated;
 
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
+  Handle<Map> map(isolate()->native_context()->generator_result_map());
 
   __ Allocate(map->instance_size(), rax, rcx, rdx, &gc_required, TAG_OBJECT);
   __ jmp(&allocated);
index fc3515f..f6ebc16 100644 (file)
@@ -36,23 +36,7 @@ namespace {
 
 using namespace v8::internal;
 
-
-void CheckIterResultObject(Isolate* isolate,
-                           Handle<JSObject> result,
-                           Handle<Object> value,
-                           bool done) {
-  CHECK(Object::GetProperty(isolate, result, "value").ToHandleChecked()
-      ->SameValue(*value));
-  CHECK(Object::GetProperty(isolate, result, "done").ToHandleChecked()
-      ->IsBoolean());
-  CHECK_EQ(Object::GetProperty(isolate, result, "done").ToHandleChecked()
-      ->BooleanValue(), done);
-}
-
-
 TEST(Set) {
-  i::FLAG_harmony_collections = true;
-
   LocalContext context;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
@@ -62,11 +46,6 @@ TEST(Set) {
   CHECK_EQ(0, ordered_set->NumberOfElements());
   CHECK_EQ(0, ordered_set->NumberOfDeletedElements());
 
-  Handle<JSSetIterator> value_iterator =
-      JSSetIterator::Create(ordered_set, JSSetIterator::kKindValues);
-  Handle<JSSetIterator> value_iterator_2 =
-      JSSetIterator::Create(ordered_set, JSSetIterator::kKindValues);
-
   Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   Handle<JSObject> obj = factory->NewJSObjectFromMap(map);
   CHECK(!ordered_set->Contains(*obj));
@@ -89,18 +68,6 @@ TEST(Set) {
   CHECK(ordered_set->Contains(*obj2));
   CHECK(ordered_set->Contains(*obj3));
 
-  // Test iteration
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator), obj1, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator), obj2, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator), obj3, false);
-  CheckIterResultObject(isolate,
-                        JSSetIterator::Next(value_iterator),
-                        factory->undefined_value(),
-                        true);
-
   // Test growth
   ordered_set = OrderedHashSet::Add(ordered_set, obj);
   Handle<JSObject> obj4 = factory->NewJSObjectFromMap(map);
@@ -114,22 +81,6 @@ TEST(Set) {
   CHECK_EQ(0, ordered_set->NumberOfDeletedElements());
   CHECK_EQ(4, ordered_set->NumberOfBuckets());
 
-  // Test iteration after growth
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj1, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj2, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj3, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj4, false);
-  CheckIterResultObject(isolate,
-                        JSSetIterator::Next(value_iterator_2),
-                        factory->undefined_value(),
-                        true);
-
   // Test shrinking
   ordered_set = OrderedHashSet::Remove(ordered_set, obj);
   ordered_set = OrderedHashSet::Remove(ordered_set, obj1);
@@ -141,8 +92,6 @@ TEST(Set) {
 
 
 TEST(Map) {
-  i::FLAG_harmony_collections = true;
-
   LocalContext context;
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
@@ -152,11 +101,6 @@ TEST(Map) {
   CHECK_EQ(0, ordered_map->NumberOfElements());
   CHECK_EQ(0, ordered_map->NumberOfDeletedElements());
 
-  Handle<JSMapIterator> value_iterator =
-      JSMapIterator::Create(ordered_map, JSMapIterator::kKindValues);
-  Handle<JSMapIterator> key_iterator =
-      JSMapIterator::Create(ordered_map, JSMapIterator::kKindKeys);
-
   Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   Handle<JSObject> obj = factory->NewJSObjectFromMap(map);
   Handle<JSObject> val = factory->NewJSObjectFromMap(map);
@@ -184,18 +128,6 @@ TEST(Map) {
   CHECK(ordered_map->Lookup(*obj2)->SameValue(*val2));
   CHECK(ordered_map->Lookup(*obj3)->SameValue(*val3));
 
-  // Test iteration
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(value_iterator), val1, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(value_iterator), val2, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(value_iterator), val3, false);
-  CheckIterResultObject(isolate,
-                        JSMapIterator::Next(value_iterator),
-                        factory->undefined_value(),
-                        true);
-
   // Test growth
   ordered_map = OrderedHashMap::Put(ordered_map, obj, val);
   Handle<JSObject> obj4 = factory->NewJSObjectFromMap(map);
@@ -209,22 +141,6 @@ TEST(Map) {
   CHECK_EQ(5, ordered_map->NumberOfElements());
   CHECK_EQ(4, ordered_map->NumberOfBuckets());
 
-  // Test iteration after growth
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj1, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj2, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj3, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj4, false);
-  CheckIterResultObject(isolate,
-                        JSMapIterator::Next(key_iterator),
-                        factory->undefined_value(),
-                        true);
-
   // Test shrinking
   ordered_map = OrderedHashMap::Put(
       ordered_map, obj, factory->the_hole_value());
index 002adaa..b33d080 100644 (file)
@@ -507,347 +507,3 @@ for (var i = 9; i >= 0; i--) {
   assertEquals('minus', m.get(0));
   assertEquals('minus', m.get(-0));
 })();
-
-
-(function TestSetForEachInvalidTypes() {
-  assertThrows(function() {
-    Set.prototype.set.forEach.call({});
-  }, TypeError);
-
-  var set = new Set();
-  assertThrows(function() {
-    set.forEach({});
-  }, TypeError);
-})();
-
-
-(function TestSetForEach() {
-  var set = new Set();
-  set.add('a');
-  set.add('b');
-  set.add('c');
-
-  var buffer = '';
-  var receiver = {};
-  set.forEach(function(v, k, s) {
-    assertSame(v, k);
-    assertSame(set, s);
-    assertSame(this, receiver);
-    buffer += v;
-    if (v === 'a') {
-      set.delete('b');
-      set.add('d');
-      set.add('e');
-      set.add('f');
-    } else if (v === 'c') {
-      set.add('b');
-      set.delete('e');
-    }
-  }, receiver);
-
-  assertEquals('acdfb', buffer);
-})();
-
-
-(function TestSetForEachAddAtEnd() {
-  var set = new Set();
-  set.add('a');
-  set.add('b');
-
-  var buffer = '';
-  set.forEach(function(v) {
-    buffer += v;
-    if (v === 'b') {
-      set.add('c');
-    }
-  });
-
-  assertEquals('abc', buffer);
-})();
-
-
-(function TestSetForEachDeleteNext() {
-  var set = new Set();
-  set.add('a');
-  set.add('b');
-  set.add('c');
-
-  var buffer = '';
-  set.forEach(function(v) {
-    buffer += v;
-    if (v === 'b') {
-      set.delete('c');
-    }
-  });
-
-  assertEquals('ab', buffer);
-})();
-
-
-(function TestSetForEachDeleteVisitedAndAddAgain() {
-  var set = new Set();
-  set.add('a');
-  set.add('b');
-  set.add('c');
-
-  var buffer = '';
-  set.forEach(function(v) {
-    buffer += v;
-    if (v === 'b') {
-      set.delete('a');
-    } else if (v === 'c') {
-      set.add('a');
-    }
-  });
-
-  assertEquals('abca', buffer);
-})();
-
-
-(function TestSetForEachClear() {
-  var set = new Set();
-  set.add('a');
-  set.add('b');
-  set.add('c');
-
-  var buffer = '';
-  set.forEach(function(v) {
-    buffer += v;
-    if (v === 'a') {
-      set.clear();
-      set.add('d');
-      set.add('e');
-    }
-  });
-
-  assertEquals('ade', buffer);
-})();
-
-
-(function TestSetForEachNested() {
-  var set = new Set();
-  set.add('a');
-  set.add('b');
-  set.add('c');
-
-  var buffer = '';
-  set.forEach(function(v) {
-    buffer += v;
-    set.forEach(function(v) {
-      buffer += v;
-      if (v === 'a') {
-        set.delete('b');
-      }
-    });
-  });
-
-  assertEquals('aaccac', buffer);
-})();
-
-
-(function TestSetForEachEarlyExit() {
-  var set = new Set();
-  set.add('a');
-  set.add('b');
-  set.add('c');
-
-  var buffer = '';
-  var ex = {};
-  try {
-    set.forEach(function(v) {
-      buffer += v;
-      throw ex;
-    });
-  } catch (e) {
-    assertEquals(ex, e);
-  }
-  assertEquals('a', buffer);
-})();
-
-
-(function TestSetForEachGC() {
-  var set = new Set();
-  for (var i = 0; i < 100; i++) {
-    set.add(i);
-  }
-
-  var accumulated = 0;
-  set.forEach(function(v) {
-    accumulated += v;
-    if (v % 10 === 0) {
-      gc();
-    }
-  });
-  assertEquals(4950, accumulated);
-})();
-
-(function TestMapForEachInvalidTypes() {
-  assertThrows(function() {
-    Map.prototype.map.forEach.call({});
-  }, TypeError);
-
-  var map = new Map();
-  assertThrows(function() {
-    map.forEach({});
-  }, TypeError);
-})();
-
-
-(function TestMapForEach() {
-  var map = new Map();
-  map.set(0, 'a');
-  map.set(1, 'b');
-  map.set(2, 'c');
-
-  var buffer = [];
-  var receiver = {};
-  map.forEach(function(v, k, m) {
-    assertEquals(map, m);
-    assertEquals(this, receiver);
-    buffer.push(k, v);
-    if (k === 0) {
-      map.delete(1);
-      map.set(3, 'd');
-      map.set(4, 'e');
-      map.set(5, 'f');
-    } else if (k === 2) {
-      map.set(1, 'B');
-      map.delete(4);
-    }
-  }, receiver);
-
-  assertArrayEquals([0, 'a', 2, 'c', 3, 'd', 5, 'f', 1, 'B'], buffer);
-})();
-
-
-(function TestMapForEachAddAtEnd() {
-  var map = new Map();
-  map.set(0, 'a');
-  map.set(1, 'b');
-
-  var buffer = [];
-  map.forEach(function(v, k) {
-    buffer.push(k, v);
-    if (k === 1) {
-      map.set(2, 'c');
-    }
-  });
-
-  assertArrayEquals([0, 'a', 1, 'b', 2, 'c'], buffer);
-})();
-
-
-(function TestMapForEachDeleteNext() {
-  var map = new Map();
-  map.set(0, 'a');
-  map.set(1, 'b');
-  map.set(2, 'c');
-
-  var buffer = [];
-  map.forEach(function(v, k) {
-    buffer.push(k, v);
-    if (k === 1) {
-      map.delete(2);
-    }
-  });
-
-  assertArrayEquals([0, 'a', 1, 'b'], buffer);
-})();
-
-
-(function TestSetForEachDeleteVisitedAndAddAgain() {
-  var map = new Map();
-  map.set(0, 'a');
-  map.set(1, 'b');
-  map.set(2, 'c');
-
-  var buffer = [];
-  map.forEach(function(v, k) {
-    buffer.push(k, v);
-    if (k === 1) {
-      map.delete(0);
-    } else if (k === 2) {
-      map.set(0, 'a');
-    }
-  });
-
-  assertArrayEquals([0, 'a', 1, 'b', 2, 'c', 0, 'a'], buffer);
-})();
-
-
-(function TestMapForEachClear() {
-  var map = new Map();
-  map.set(0, 'a');
-  map.set(1, 'b');
-  map.set(2, 'c');
-
-  var buffer = [];
-  map.forEach(function(v, k) {
-    buffer.push(k, v);
-    if (k === 0) {
-      map.clear();
-      map.set(3, 'd');
-      map.set(4, 'e');
-    }
-  });
-
-  assertArrayEquals([0, 'a', 3, 'd', 4, 'e'], buffer);
-})();
-
-
-(function TestMapForEachNested() {
-  var map = new Map();
-  map.set(0, 'a');
-  map.set(1, 'b');
-  map.set(2, 'c');
-
-  var buffer = [];
-  map.forEach(function(v, k) {
-    buffer.push(k, v);
-    map.forEach(function(v, k) {
-      buffer.push(k, v);
-      if (k === 0) {
-        map.delete(1);
-      }
-    });
-  });
-
-  assertArrayEquals([0, 'a', 0, 'a', 2, 'c', 2, 'c', 0, 'a', 2, 'c'], buffer);
-})();
-
-
-(function TestMapForEachEarlyExit() {
-  var map = new Map();
-  map.set(0, 'a');
-  map.set(1, 'b');
-  map.set(2, 'c');
-
-  var buffer = [];
-  var ex = {};
-  try {
-    map.forEach(function(v, k) {
-      buffer.push(k, v);
-      throw ex;
-    });
-  } catch (e) {
-    assertEquals(ex, e);
-  }
-  assertArrayEquals([0, 'a'], buffer);
-})();
-
-
-(function TestMapForEachGC() {
-  var map = new Map();
-  for (var i = 0; i < 100; i++) {
-    map.set(i, i);
-  }
-
-  var accumulated = 0;
-  map.forEach(function(v) {
-    accumulated += v;
-    if (v % 10 === 0) {
-      gc();
-    }
-  });
-  assertEquals(4950, accumulated);
-})();