Revert "ES6: Add support for Map/Set forEach"

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
This commit is contained in:
adamk@chromium.org 2014-04-16 21:19:25 +00:00
parent 7c300d1f83
commit 91618cf1e9
22 changed files with 71 additions and 1213 deletions

View 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);

View 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 }

View File

@ -31,6 +31,11 @@
// 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() {

View 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);
}
}

View 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
));
}

View 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.

View 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

View 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);

View 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);

View 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;

View 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);

View 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());
}

View 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;
}

View 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()));

View 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);

View 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()),

View 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:

View 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);

View 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) \

View 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);

View 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());

View 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);
})();