1// Copyright 2014 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/execution/arguments-inl.h" 6#include "src/heap/factory.h" 7#include "src/heap/heap-inl.h" // For ToBoolean. TODO(jkummerow): Drop. 8#include "src/logging/counters.h" 9#include "src/numbers/conversions-inl.h" 10#include "src/objects/hash-table-inl.h" 11#include "src/objects/js-collection-inl.h" 12#include "src/runtime/runtime-utils.h" 13 14namespace v8 { 15namespace internal { 16 17RUNTIME_FUNCTION(Runtime_TheHole) { 18 SealHandleScope shs(isolate); 19 DCHECK_EQ(0, args.length()); 20 return ReadOnlyRoots(isolate).the_hole_value(); 21} 22 23RUNTIME_FUNCTION(Runtime_SetGrow) { 24 HandleScope scope(isolate); 25 DCHECK_EQ(1, args.length()); 26 Handle<JSSet> holder = args.at<JSSet>(0); 27 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()), isolate); 28 MaybeHandle<OrderedHashSet> table_candidate = 29 OrderedHashSet::EnsureGrowable(isolate, table); 30 if (!table_candidate.ToHandle(&table)) { 31 THROW_NEW_ERROR_RETURN_FAILURE( 32 isolate, 33 NewRangeError(MessageTemplate::kCollectionGrowFailed, 34 isolate->factory()->NewStringFromAsciiChecked("Set"))); 35 } 36 holder->set_table(*table); 37 return ReadOnlyRoots(isolate).undefined_value(); 38} 39 40RUNTIME_FUNCTION(Runtime_SetShrink) { 41 HandleScope scope(isolate); 42 DCHECK_EQ(1, args.length()); 43 Handle<JSSet> holder = args.at<JSSet>(0); 44 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()), isolate); 45 table = OrderedHashSet::Shrink(isolate, table); 46 holder->set_table(*table); 47 return ReadOnlyRoots(isolate).undefined_value(); 48} 49 50RUNTIME_FUNCTION(Runtime_MapShrink) { 51 HandleScope scope(isolate); 52 DCHECK_EQ(1, args.length()); 53 Handle<JSMap> holder = args.at<JSMap>(0); 54 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()), isolate); 55 table = OrderedHashMap::Shrink(isolate, table); 56 holder->set_table(*table); 57 return ReadOnlyRoots(isolate).undefined_value(); 58} 59 60RUNTIME_FUNCTION(Runtime_MapGrow) { 61 HandleScope scope(isolate); 62 DCHECK_EQ(1, args.length()); 63 Handle<JSMap> holder = args.at<JSMap>(0); 64 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()), isolate); 65 MaybeHandle<OrderedHashMap> table_candidate = 66 OrderedHashMap::EnsureGrowable(isolate, table); 67 if (!table_candidate.ToHandle(&table)) { 68 THROW_NEW_ERROR_RETURN_FAILURE( 69 isolate, 70 NewRangeError(MessageTemplate::kCollectionGrowFailed, 71 isolate->factory()->NewStringFromAsciiChecked("Map"))); 72 } 73 holder->set_table(*table); 74 return ReadOnlyRoots(isolate).undefined_value(); 75} 76 77RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { 78 HandleScope scope(isolate); 79 DCHECK_EQ(3, args.length()); 80 Handle<JSWeakCollection> weak_collection = args.at<JSWeakCollection>(0); 81 Handle<Object> key = args.at(1); 82 int hash = args.smi_value_at(2); 83 84#ifdef DEBUG 85 DCHECK(key->CanBeHeldWeakly()); 86 DCHECK(EphemeronHashTable::IsKey(ReadOnlyRoots(isolate), *key)); 87 Handle<EphemeronHashTable> table( 88 EphemeronHashTable::cast(weak_collection->table()), isolate); 89 // Should only be called when shrinking the table is necessary. See 90 // HashTable::Shrink(). 91 DCHECK(table->NumberOfElements() - 1 <= (table->Capacity() >> 2) && 92 table->NumberOfElements() - 1 >= 16); 93#endif 94 95 bool was_present = JSWeakCollection::Delete(weak_collection, key, hash); 96 return isolate->heap()->ToBoolean(was_present); 97} 98 99RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { 100 HandleScope scope(isolate); 101 DCHECK_EQ(4, args.length()); 102 Handle<JSWeakCollection> weak_collection = args.at<JSWeakCollection>(0); 103 Handle<Object> key = args.at(1); 104 Handle<Object> value = args.at(2); 105 int hash = args.smi_value_at(3); 106 107#ifdef DEBUG 108 DCHECK(key->CanBeHeldWeakly()); 109 DCHECK(EphemeronHashTable::IsKey(ReadOnlyRoots(isolate), *key)); 110 Handle<EphemeronHashTable> table( 111 EphemeronHashTable::cast(weak_collection->table()), isolate); 112 // Should only be called when rehashing or resizing the table is necessary. 113 // See EphemeronHashTable::Put() and HashTable::HasSufficientCapacityToAdd(). 114 DCHECK((table->NumberOfDeletedElements() << 1) > table->NumberOfElements() || 115 !table->HasSufficientCapacityToAdd(1)); 116#endif 117 118 JSWeakCollection::Set(weak_collection, key, value, hash); 119 return *weak_collection; 120} 121 122} // namespace internal 123} // namespace v8 124