diff options
Diffstat (limited to 'deps/v8/src/runtime/runtime-collections.cc')
-rw-r--r-- | deps/v8/src/runtime/runtime-collections.cc | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/deps/v8/src/runtime/runtime-collections.cc b/deps/v8/src/runtime/runtime-collections.cc new file mode 100644 index 0000000000..d0d6aa64fb --- /dev/null +++ b/deps/v8/src/runtime/runtime-collections.cc @@ -0,0 +1,347 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/v8.h" + +#include "src/arguments.h" +#include "src/runtime/runtime.h" +#include "src/runtime/runtime-utils.h" + + +namespace v8 { +namespace internal { + +RUNTIME_FUNCTION(Runtime_SetInitialize) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); + Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet(); + holder->set_table(*table); + return *holder; +} + + +RUNTIME_FUNCTION(Runtime_SetAdd) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table())); + table = OrderedHashSet::Add(table, key); + holder->set_table(*table); + return *holder; +} + + +RUNTIME_FUNCTION(Runtime_SetHas) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table())); + return isolate->heap()->ToBoolean(table->Contains(key)); +} + + +RUNTIME_FUNCTION(Runtime_SetDelete) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table())); + bool was_present = false; + table = OrderedHashSet::Remove(table, key, &was_present); + holder->set_table(*table); + return isolate->heap()->ToBoolean(was_present); +} + + +RUNTIME_FUNCTION(Runtime_SetClear) { + HandleScope scope(isolate); + DCHECK(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(Runtime_SetGetSize) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); + Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table())); + return Smi::FromInt(table->NumberOfElements()); +} + + +RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) { + HandleScope scope(isolate); + DCHECK(args.length() == 3); + CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); + CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1); + CONVERT_SMI_ARG_CHECKED(kind, 2) + RUNTIME_ASSERT(kind == JSSetIterator::kKindValues || + kind == JSSetIterator::kKindEntries); + Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table())); + holder->set_table(*table); + holder->set_index(Smi::FromInt(0)); + holder->set_kind(Smi::FromInt(kind)); + return isolate->heap()->undefined_value(); +} + + +RUNTIME_FUNCTION(Runtime_SetIteratorNext) { + SealHandleScope shs(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_CHECKED(JSSetIterator, holder, 0); + CONVERT_ARG_CHECKED(JSArray, value_array, 1); + return holder->Next(value_array); +} + + +RUNTIME_FUNCTION(Runtime_MapInitialize) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); + Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap(); + holder->set_table(*table); + return *holder; +} + + +RUNTIME_FUNCTION(Runtime_MapGet) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); + Handle<Object> lookup(table->Lookup(key), isolate); + return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup; +} + + +RUNTIME_FUNCTION(Runtime_MapHas) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); + Handle<Object> lookup(table->Lookup(key), isolate); + return isolate->heap()->ToBoolean(!lookup->IsTheHole()); +} + + +RUNTIME_FUNCTION(Runtime_MapDelete) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); + bool was_present = false; + Handle<OrderedHashMap> new_table = + OrderedHashMap::Remove(table, key, &was_present); + holder->set_table(*new_table); + return isolate->heap()->ToBoolean(was_present); +} + + +RUNTIME_FUNCTION(Runtime_MapClear) { + HandleScope scope(isolate); + DCHECK(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(Runtime_MapSet) { + HandleScope scope(isolate); + DCHECK(args.length() == 3); + CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); + Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); + Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value); + holder->set_table(*new_table); + return *holder; +} + + +RUNTIME_FUNCTION(Runtime_MapGetSize) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); + Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); + return Smi::FromInt(table->NumberOfElements()); +} + + +RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) { + HandleScope scope(isolate); + DCHECK(args.length() == 3); + CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); + CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1); + CONVERT_SMI_ARG_CHECKED(kind, 2) + RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys || + kind == JSMapIterator::kKindValues || + kind == JSMapIterator::kKindEntries); + Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table())); + holder->set_table(*table); + holder->set_index(Smi::FromInt(0)); + holder->set_kind(Smi::FromInt(kind)); + return isolate->heap()->undefined_value(); +} + + +RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); + Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); + Handle<FixedArray> entries = + isolate->factory()->NewFixedArray(table->NumberOfElements() * 2); + { + DisallowHeapAllocation no_gc; + int number_of_non_hole_elements = 0; + for (int i = 0; i < table->Capacity(); i++) { + Handle<Object> key(table->KeyAt(i), isolate); + if (table->IsKey(*key)) { + entries->set(number_of_non_hole_elements++, *key); + Object* value = table->Lookup(key); + entries->set(number_of_non_hole_elements++, value); + } + } + DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements); + } + return *isolate->factory()->NewJSArrayWithElements(entries); +} + + +RUNTIME_FUNCTION(Runtime_MapIteratorNext) { + SealHandleScope shs(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_CHECKED(JSMapIterator, holder, 0); + CONVERT_ARG_CHECKED(JSArray, value_array, 1); + return holder->Next(value_array); +} + + +static Handle<JSWeakCollection> WeakCollectionInitialize( + Isolate* isolate, Handle<JSWeakCollection> weak_collection) { + DCHECK(weak_collection->map()->inobject_properties() == 0); + Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0); + weak_collection->set_table(*table); + return weak_collection; +} + + +RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); + return *WeakCollectionInitialize(isolate, weak_collection); +} + + +RUNTIME_FUNCTION(Runtime_WeakCollectionGet) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol()); + Handle<ObjectHashTable> table( + ObjectHashTable::cast(weak_collection->table())); + RUNTIME_ASSERT(table->IsKey(*key)); + Handle<Object> lookup(table->Lookup(key), isolate); + return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup; +} + + +RUNTIME_FUNCTION(Runtime_WeakCollectionHas) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol()); + Handle<ObjectHashTable> table( + ObjectHashTable::cast(weak_collection->table())); + RUNTIME_ASSERT(table->IsKey(*key)); + Handle<Object> lookup(table->Lookup(key), isolate); + return isolate->heap()->ToBoolean(!lookup->IsTheHole()); +} + + +RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol()); + Handle<ObjectHashTable> table( + ObjectHashTable::cast(weak_collection->table())); + RUNTIME_ASSERT(table->IsKey(*key)); + bool was_present = false; + Handle<ObjectHashTable> new_table = + ObjectHashTable::Remove(table, key, &was_present); + weak_collection->set_table(*new_table); + return isolate->heap()->ToBoolean(was_present); +} + + +RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { + HandleScope scope(isolate); + DCHECK(args.length() == 3); + CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); + RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol()); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); + Handle<ObjectHashTable> table( + ObjectHashTable::cast(weak_collection->table())); + RUNTIME_ASSERT(table->IsKey(*key)); + Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value); + weak_collection->set_table(*new_table); + return *weak_collection; +} + + +RUNTIME_FUNCTION(Runtime_GetWeakSetValues) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); + Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); + Handle<FixedArray> values = + isolate->factory()->NewFixedArray(table->NumberOfElements()); + { + DisallowHeapAllocation no_gc; + int number_of_non_hole_elements = 0; + for (int i = 0; i < table->Capacity(); i++) { + Handle<Object> key(table->KeyAt(i), isolate); + if (table->IsKey(*key)) { + values->set(number_of_non_hole_elements++, *key); + } + } + DCHECK_EQ(table->NumberOfElements(), number_of_non_hole_elements); + } + return *isolate->factory()->NewJSArrayWithElements(values); +} + + +RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) { + HandleScope scope(isolate); + DCHECK(args.length() == 0); + // TODO(adamk): Currently this runtime function is only called three times per + // isolate. If it's called more often, the map should be moved into the + // strong root list. + Handle<Map> map = + isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize); + Handle<JSWeakMap> weakmap = + Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map)); + return *WeakCollectionInitialize(isolate, weakmap); +} +} +} // namespace v8::internal |