From b955d842891c0ab3700e6e261faf54b67aee9155 Mon Sep 17 00:00:00 2001 From: Jaroslav Sevcik Date: Mon, 24 Jul 2017 13:45:28 +0200 Subject: [PATCH] [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 Commit-Queue: Benedikt Meurer Reviewed-by: Benedikt Meurer Cr-Commit-Position: refs/heads/master@{#46839} --- src/bootstrapper.cc | 4 ++ src/builtins/builtins-collections-gen.cc | 58 ++++++++++++++++++++++++ src/builtins/builtins-definitions.h | 1 + src/js/collection.js | 31 ------------- 4 files changed, 63 insertions(+), 31 deletions(-) diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 38aed2d52c..1502598aa0 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -3028,6 +3028,10 @@ void Genesis::InitializeGlobal(Handle global_object, SimpleInstallFunction(prototype, "has", Builtins::kMapHas, 1, true); native_context()->set_map_has(*map_has); + Handle map_delete = SimpleInstallFunction( + prototype, "delete", Builtins::kMapDelete, 1, true); + native_context()->set_map_delete(*map_delete); + SimpleInstallFunction(prototype, "clear", Builtins::kMapClear, 0, true); Handle entries = SimpleInstallFunction( prototype, "entries", Builtins::kMapPrototypeEntries, 0, true); diff --git a/src/builtins/builtins-collections-gen.cc b/src/builtins/builtins-collections-gen.cc index 8faef1b4d0..3285f2417f 100644 --- a/src/builtins/builtins-collections-gen.cc +++ b/src/builtins/builtins-collections-gen.cc @@ -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); diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h index f1e2bfbc8f..49773c0431 100644 --- a/src/builtins/builtins-definitions.h +++ b/src/builtins/builtins-definitions.h @@ -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) \ diff --git a/src/js/collection.js b/src/js/collection.js index 975ac34760..f2991693c0 100644 --- a/src/js/collection.js +++ b/src/js/collection.js @@ -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, ]);