blob: 723b68071998d93b1dadd842ec7636f13bb04ae0 [file]
// Copyright 2018 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.
#ifndef V8_BUILTINS_BUILTINS_COLLECTIONS_GEN_H_
#define V8_BUILTINS_BUILTINS_COLLECTIONS_GEN_H_
#include "src/codegen/code-stub-assembler.h"
namespace v8 {
namespace internal {
void BranchIfIterableWithOriginalKeyOrValueMapIterator(
compiler::CodeAssemblerState* state, TNode<Object> iterable,
TNode<Context> context, compiler::CodeAssemblerLabel* if_true,
compiler::CodeAssemblerLabel* if_false);
void BranchIfIterableWithOriginalValueSetIterator(
compiler::CodeAssemblerState* state, TNode<Object> iterable,
TNode<Context> context, compiler::CodeAssemblerLabel* if_true,
compiler::CodeAssemblerLabel* if_false);
class BaseCollectionsAssembler : public CodeStubAssembler {
public:
explicit BaseCollectionsAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
virtual ~BaseCollectionsAssembler() = default;
void GotoIfCannotBeHeldWeakly(const TNode<Object> obj,
Label* if_cannot_be_held_weakly);
protected:
enum Variant { kMap, kSet, kWeakMap, kWeakSet };
// Adds an entry to a collection. For Maps, properly handles extracting the
// key and value from the entry (see LoadKeyValue()).
void AddConstructorEntry(Variant variant, TNode<Context> context,
TNode<Object> collection, TNode<Object> add_function,
TNode<Object> key_value,
Label* if_may_have_side_effects = nullptr,
Label* if_exception = nullptr,
TVariable<Object>* var_exception = nullptr);
// Adds constructor entries to a collection. Choosing a fast path when
// possible.
void AddConstructorEntries(Variant variant, TNode<Context> context,
TNode<Context> native_context,
TNode<HeapObject> collection,
TNode<Object> initial_entries);
// Fast path for adding constructor entries. Assumes the entries are a fast
// JS array (see CodeStubAssembler::BranchIfFastJSArray()).
void AddConstructorEntriesFromFastJSArray(
Variant variant, TNode<Context> context, TNode<Context> native_context,
TNode<Object> collection, TNode<JSArray> fast_jsarray,
Label* if_may_have_side_effects, TVariable<IntPtrT>& var_current_index);
// Adds constructor entries to a collection using the iterator protocol.
void AddConstructorEntriesFromIterable(
Variant variant, TNode<Context> context, TNode<Context> native_context,
TNode<Object> collection, TNode<Object> iterable, Label* if_exception,
TVariable<JSReceiver>* var_iterator, TVariable<Object>* var_exception);
// Constructs a collection instance. Choosing a fast path when possible.
TNode<JSObject> AllocateJSCollection(TNode<Context> context,
TNode<JSFunction> constructor,
TNode<JSReceiver> new_target);
// Fast path for constructing a collection instance if the constructor
// function has not been modified.
TNode<JSObject> AllocateJSCollectionFast(TNode<JSFunction> constructor);
// Fallback for constructing a collection instance if the constructor function
// has been modified.
TNode<JSObject> AllocateJSCollectionSlow(TNode<Context> context,
TNode<JSFunction> constructor,
TNode<JSReceiver> new_target);
// Allocates the backing store for a collection.
virtual TNode<HeapObject> AllocateTable(
Variant variant, TNode<IntPtrT> at_least_space_for) = 0;
// Main entry point for a collection constructor builtin.
void GenerateConstructor(Variant variant,
Handle<String> constructor_function_name,
TNode<Object> new_target, TNode<IntPtrT> argc,
TNode<Context> context);
// Retrieves the collection function that adds an entry. `set` for Maps and
// `add` for Sets.
TNode<Object> GetAddFunction(Variant variant, TNode<Context> context,
TNode<Object> collection);
// Retrieves the collection constructor function.
TNode<JSFunction> GetConstructor(Variant variant,
TNode<Context> native_context);
// Retrieves the initial collection function that adds an entry. Should only
// be called when it is certain that a collection prototype's map hasn't been
// changed.
TNode<JSFunction> GetInitialAddFunction(Variant variant,
TNode<Context> native_context);
// Checks whether {collection}'s initial add/set function has been modified
// (depending on {variant}, loaded from {native_context}).
void GotoIfInitialAddFunctionModified(Variant variant,
TNode<NativeContext> native_context,
TNode<HeapObject> collection,
Label* if_modified);
// Gets root index for the name of the add/set function.
RootIndex GetAddFunctionNameIndex(Variant variant);
// Retrieves the offset to access the backing table from the collection.
int GetTableOffset(Variant variant);
// Estimates the number of entries the collection will have after adding the
// entries passed in the constructor. AllocateTable() can use this to avoid
// the time of growing/rehashing when adding the constructor entries.
TNode<IntPtrT> EstimatedInitialSize(TNode<Object> initial_entries,
TNode<BoolT> is_fast_jsarray);
// Determines whether the collection's prototype has been modified.
TNode<BoolT> HasInitialCollectionPrototype(Variant variant,
TNode<Context> native_context,
TNode<Object> collection);
// Gets the initial prototype map for given collection {variant}.
TNode<Map> GetInitialCollectionPrototype(Variant variant,
TNode<Context> native_context);
// Loads an element from a fixed array. If the element is the hole, returns
// `undefined`.
TNode<Object> LoadAndNormalizeFixedArrayElement(TNode<FixedArray> elements,
TNode<IntPtrT> index);
// Loads an element from a fixed double array. If the element is the hole,
// returns `undefined`.
TNode<Object> LoadAndNormalizeFixedDoubleArrayElement(
TNode<HeapObject> elements, TNode<IntPtrT> index);
};
class WeakCollectionsBuiltinsAssembler : public BaseCollectionsAssembler {
public:
explicit WeakCollectionsBuiltinsAssembler(compiler::CodeAssemblerState* state)
: BaseCollectionsAssembler(state) {}
protected:
void AddEntry(TNode<EphemeronHashTable> table, TNode<IntPtrT> key_index,
TNode<Object> key, TNode<Object> value,
TNode<IntPtrT> number_of_elements);
TNode<HeapObject> AllocateTable(Variant variant,
TNode<IntPtrT> at_least_space_for) override;
TNode<IntPtrT> GetHash(const TNode<HeapObject> key, Label* if_no_hash);
// Generates and sets the identity for a JSRececiver.
TNode<Smi> CreateIdentityHash(TNode<Object> receiver);
TNode<IntPtrT> EntryMask(TNode<IntPtrT> capacity);
// Builds code that finds the EphemeronHashTable entry for a {key} using the
// comparison code generated by {key_compare}. The key index is returned if
// the {key} is found.
using KeyComparator =
std::function<void(TNode<Object> entry_key, Label* if_same)>;
TNode<IntPtrT> FindKeyIndex(TNode<HeapObject> table, TNode<IntPtrT> key_hash,
TNode<IntPtrT> entry_mask,
const KeyComparator& key_compare);
// Builds code that finds an EphemeronHashTable entry available for a new
// entry.
TNode<IntPtrT> FindKeyIndexForInsertion(TNode<HeapObject> table,
TNode<IntPtrT> key_hash,
TNode<IntPtrT> entry_mask);
// Builds code that finds the EphemeronHashTable entry with key that matches
// {key} and returns the entry's key index. If {key} cannot be found, jumps to
// {if_not_found}.
TNode<IntPtrT> FindKeyIndexForKey(TNode<HeapObject> table, TNode<Object> key,
TNode<IntPtrT> hash,
TNode<IntPtrT> entry_mask,
Label* if_not_found);
TNode<Word32T> InsufficientCapacityToAdd(TNode<IntPtrT> capacity,
TNode<IntPtrT> number_of_elements,
TNode<IntPtrT> number_of_deleted);
TNode<IntPtrT> KeyIndexFromEntry(TNode<IntPtrT> entry);
TNode<IntPtrT> LoadNumberOfElements(TNode<EphemeronHashTable> table,
int offset);
TNode<IntPtrT> LoadNumberOfDeleted(TNode<EphemeronHashTable> table,
int offset = 0);
TNode<EphemeronHashTable> LoadTable(TNode<JSWeakCollection> collection);
TNode<IntPtrT> LoadTableCapacity(TNode<EphemeronHashTable> table);
void RemoveEntry(TNode<EphemeronHashTable> table, TNode<IntPtrT> key_index,
TNode<IntPtrT> number_of_elements);
TNode<BoolT> ShouldRehash(TNode<IntPtrT> number_of_elements,
TNode<IntPtrT> number_of_deleted);
TNode<Word32T> ShouldShrink(TNode<IntPtrT> capacity,
TNode<IntPtrT> number_of_elements);
TNode<IntPtrT> ValueIndexFromKeyIndex(TNode<IntPtrT> key_index);
};
} // namespace internal
} // namespace v8
#endif // V8_BUILTINS_BUILTINS_COLLECTIONS_GEN_H_