[builtins] Port Map.p.delete to CSA.
Bug: v8:5717 Change-Id: Iff5b71b9e27b3e4a790118cbd4877b4460d07b1d Reviewed-on: https://chromium-review.googlesource.com/582810 Commit-Queue: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#46839}
This commit is contained in:
parent
e8c9649e25
commit
b955d84289
@ -3028,6 +3028,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
SimpleInstallFunction(prototype, "has", Builtins::kMapHas, 1, true);
|
||||
native_context()->set_map_has(*map_has);
|
||||
|
||||
Handle<JSFunction> map_delete = SimpleInstallFunction(
|
||||
prototype, "delete", Builtins::kMapDelete, 1, true);
|
||||
native_context()->set_map_delete(*map_delete);
|
||||
|
||||
SimpleInstallFunction(prototype, "clear", Builtins::kMapClear, 0, true);
|
||||
Handle<JSFunction> entries = SimpleInstallFunction(
|
||||
prototype, "entries", Builtins::kMapPrototypeEntries, 0, true);
|
||||
|
@ -966,6 +966,64 @@ void CollectionsBuiltinsAssembler::StoreOrderedHashMapNewEntry(
|
||||
SmiAdd(number_of_elements, SmiConstant(1)));
|
||||
}
|
||||
|
||||
TF_BUILTIN(MapDelete, CollectionsBuiltinsAssembler) {
|
||||
Node* const receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* key = Parameter(Descriptor::kKey);
|
||||
Node* const context = Parameter(Descriptor::kContext);
|
||||
|
||||
ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE,
|
||||
"Map.prototype.delete");
|
||||
|
||||
Node* const table = LoadObjectField(receiver, JSMap::kTableOffset);
|
||||
|
||||
VARIABLE(entry_start_position_or_hash, MachineType::PointerRepresentation(),
|
||||
IntPtrConstant(0));
|
||||
Label entry_found(this), not_found(this);
|
||||
|
||||
TryLookupOrderedHashMapIndex(table, key, context,
|
||||
&entry_start_position_or_hash, &entry_found,
|
||||
¬_found);
|
||||
|
||||
BIND(¬_found);
|
||||
Return(FalseConstant());
|
||||
|
||||
BIND(&entry_found);
|
||||
// If we found the entry, mark the entry as deleted.
|
||||
StoreFixedArrayElement(table, entry_start_position_or_hash.value(),
|
||||
TheHoleConstant(), UPDATE_WRITE_BARRIER,
|
||||
kPointerSize * OrderedHashMap::kHashTableStartIndex);
|
||||
StoreFixedArrayElement(table, entry_start_position_or_hash.value(),
|
||||
TheHoleConstant(), UPDATE_WRITE_BARRIER,
|
||||
kPointerSize * (OrderedHashMap::kHashTableStartIndex +
|
||||
OrderedHashMap::kValueOffset));
|
||||
|
||||
// Decrement the number of elements, increment the number of deleted elements.
|
||||
Node* const number_of_elements =
|
||||
SmiSub(LoadObjectField(table, OrderedHashMap::kNumberOfElementsOffset),
|
||||
SmiConstant(1));
|
||||
StoreObjectFieldNoWriteBarrier(table, OrderedHashMap::kNumberOfElementsOffset,
|
||||
number_of_elements);
|
||||
Node* const number_of_deleted = SmiAdd(
|
||||
LoadObjectField(table, OrderedHashMap::kNumberOfDeletedElementsOffset),
|
||||
SmiConstant(1));
|
||||
StoreObjectFieldNoWriteBarrier(
|
||||
table, OrderedHashMap::kNumberOfDeletedElementsOffset, number_of_deleted);
|
||||
|
||||
Node* const number_of_buckets =
|
||||
LoadFixedArrayElement(table, OrderedHashMap::kNumberOfBucketsIndex);
|
||||
|
||||
// If there fewer elements than #buckets / 2, shrink the table.
|
||||
Label shrink(this);
|
||||
GotoIf(SmiLessThan(SmiAdd(number_of_elements, number_of_elements),
|
||||
number_of_buckets),
|
||||
&shrink);
|
||||
Return(TrueConstant());
|
||||
|
||||
BIND(&shrink);
|
||||
CallRuntime(Runtime::kMapShrink, context, receiver);
|
||||
Return(TrueConstant());
|
||||
}
|
||||
|
||||
TF_BUILTIN(MapPrototypeEntries, CollectionsBuiltinsAssembler) {
|
||||
Node* const receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* const context = Parameter(Descriptor::kContext);
|
||||
|
@ -578,6 +578,7 @@ namespace internal {
|
||||
TFS(MapLookupHashIndex, kTable, kKey) \
|
||||
TFJ(MapConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||
TFJ(MapSet, 2, kKey, kValue) \
|
||||
TFJ(MapDelete, 1, kKey) \
|
||||
TFJ(MapGet, 1, kKey) \
|
||||
TFJ(MapHas, 1, kKey) \
|
||||
CPP(MapClear) \
|
||||
|
@ -186,41 +186,10 @@ DEFINE_METHODS(
|
||||
}
|
||||
);
|
||||
|
||||
// Harmony Map
|
||||
|
||||
//Set up the non-enumerable functions on the Map prototype object.
|
||||
DEFINE_METHODS(
|
||||
GlobalMap.prototype,
|
||||
{
|
||||
delete(key) {
|
||||
if (!IS_MAP(this)) {
|
||||
throw %make_type_error(kIncompatibleMethodReceiver,
|
||||
'Map.prototype.delete', this);
|
||||
}
|
||||
var table = %_JSCollectionGetTable(this);
|
||||
var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
||||
var hash = GetHash(key);
|
||||
var entry = MapFindEntry(table, numBuckets, key, hash);
|
||||
if (entry === NOT_FOUND) return false;
|
||||
|
||||
var nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table) - 1;
|
||||
var nod = ORDERED_HASH_TABLE_DELETED_COUNT(table) + 1;
|
||||
var index = ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets);
|
||||
FIXED_ARRAY_SET(table, index, %_TheHole());
|
||||
FIXED_ARRAY_SET(table, index + 1, %_TheHole());
|
||||
ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, nof);
|
||||
ORDERED_HASH_TABLE_SET_DELETED_COUNT(table, nod);
|
||||
if (nof < (numBuckets >>> 1)) %MapShrink(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Exports
|
||||
|
||||
%InstallToContext([
|
||||
"map_delete", GlobalMap.prototype.delete,
|
||||
"set_add", GlobalSet.prototype.add,
|
||||
"set_delete", GlobalSet.prototype.delete,
|
||||
]);
|
||||
|
Loading…
Reference in New Issue
Block a user