[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);
|
SimpleInstallFunction(prototype, "has", Builtins::kMapHas, 1, true);
|
||||||
native_context()->set_map_has(*map_has);
|
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);
|
SimpleInstallFunction(prototype, "clear", Builtins::kMapClear, 0, true);
|
||||||
Handle<JSFunction> entries = SimpleInstallFunction(
|
Handle<JSFunction> entries = SimpleInstallFunction(
|
||||||
prototype, "entries", Builtins::kMapPrototypeEntries, 0, true);
|
prototype, "entries", Builtins::kMapPrototypeEntries, 0, true);
|
||||||
|
@ -966,6 +966,64 @@ void CollectionsBuiltinsAssembler::StoreOrderedHashMapNewEntry(
|
|||||||
SmiAdd(number_of_elements, SmiConstant(1)));
|
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) {
|
TF_BUILTIN(MapPrototypeEntries, CollectionsBuiltinsAssembler) {
|
||||||
Node* const receiver = Parameter(Descriptor::kReceiver);
|
Node* const receiver = Parameter(Descriptor::kReceiver);
|
||||||
Node* const context = Parameter(Descriptor::kContext);
|
Node* const context = Parameter(Descriptor::kContext);
|
||||||
|
@ -578,6 +578,7 @@ namespace internal {
|
|||||||
TFS(MapLookupHashIndex, kTable, kKey) \
|
TFS(MapLookupHashIndex, kTable, kKey) \
|
||||||
TFJ(MapConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
TFJ(MapConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||||
TFJ(MapSet, 2, kKey, kValue) \
|
TFJ(MapSet, 2, kKey, kValue) \
|
||||||
|
TFJ(MapDelete, 1, kKey) \
|
||||||
TFJ(MapGet, 1, kKey) \
|
TFJ(MapGet, 1, kKey) \
|
||||||
TFJ(MapHas, 1, kKey) \
|
TFJ(MapHas, 1, kKey) \
|
||||||
CPP(MapClear) \
|
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
|
// Exports
|
||||||
|
|
||||||
%InstallToContext([
|
%InstallToContext([
|
||||||
"map_delete", GlobalMap.prototype.delete,
|
|
||||||
"set_add", GlobalSet.prototype.add,
|
"set_add", GlobalSet.prototype.add,
|
||||||
"set_delete", GlobalSet.prototype.delete,
|
"set_delete", GlobalSet.prototype.delete,
|
||||||
]);
|
]);
|
||||||
|
Loading…
Reference in New Issue
Block a user