Commit c25744c2 authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[Collections] Port Map.get to CSA/C++

Bug: v8:5717, v8:6354, v8:6410
Change-Id: Ie652f4358f2a68c7ea76d546e26a6b4fb815df4a
Reviewed-on: https://chromium-review.googlesource.com/518923
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45664}
parent 51d38345
......@@ -1589,6 +1589,13 @@ ExternalReference ExternalReference::search_string_raw(Isolate* isolate) {
return ExternalReference(Redirect(isolate, FUNCTION_ADDR(f)));
}
template <typename CollectionType, int entrysize>
ExternalReference ExternalReference::orderedhashtable_get_raw(
Isolate* isolate) {
auto f = OrderedHashTable<CollectionType, entrysize>::Get;
return ExternalReference(Redirect(isolate, FUNCTION_ADDR(f)));
}
ExternalReference ExternalReference::try_internalize_string_function(
Isolate* isolate) {
return ExternalReference(Redirect(
......@@ -1619,6 +1626,11 @@ ExternalReference::search_string_raw<const uc16, const uint8_t>(Isolate*);
template ExternalReference
ExternalReference::search_string_raw<const uc16, const uc16>(Isolate*);
template ExternalReference
ExternalReference::orderedhashtable_get_raw<OrderedHashMap, 2>(Isolate*);
template ExternalReference
ExternalReference::orderedhashtable_get_raw<OrderedHashSet, 1>(Isolate*);
ExternalReference ExternalReference::page_flags(Page* page) {
return ExternalReference(reinterpret_cast<Address>(page) +
MemoryChunk::kFlagsOffset);
......
......@@ -1024,6 +1024,9 @@ class ExternalReference BASE_EMBEDDED {
template <typename SubjectChar, typename PatternChar>
static ExternalReference search_string_raw(Isolate* isolate);
template <typename CollectionType, int entrysize>
static ExternalReference orderedhashtable_get_raw(Isolate* isolate);
static ExternalReference page_flags(Page* page);
static ExternalReference ForDeoptEntry(Address entry);
......
......@@ -2945,6 +2945,11 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
prototype, factory->to_string_tag_symbol(), factory->Map_string(),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
Handle<JSFunction> map_get =
SimpleInstallFunction(prototype, "get", Builtins::kMapGet, 1, true);
InstallWithIntrinsicDefaultProto(isolate, map_get,
Context::MAP_GET_METHOD_INDEX);
InstallSpeciesGetter(js_map_fun);
}
......
......@@ -19,6 +19,9 @@ class CollectionsBuiltinsAssembler : public CodeStubAssembler {
protected:
Node* AllocateJSMap(Node* js_map_function);
template <typename CollectionType, int entrysize>
Node* CallGetRaw(Node* const table, Node* const key);
};
Node* CollectionsBuiltinsAssembler::AllocateJSMap(Node* js_map_function) {
......@@ -152,5 +155,34 @@ TF_BUILTIN(MapConstructor, CollectionsBuiltinsAssembler) {
Return(var_result.value());
}
template <typename CollectionType, int entrysize>
Node* CollectionsBuiltinsAssembler::CallGetRaw(Node* const table,
Node* const key) {
Node* const function_addr = ExternalConstant(
ExternalReference::orderedhashtable_get_raw<CollectionType, entrysize>(
isolate()));
Node* const isolate_ptr =
ExternalConstant(ExternalReference::isolate_address(isolate()));
MachineType type_ptr = MachineType::Pointer();
MachineType type_tagged = MachineType::AnyTagged();
Node* const result =
CallCFunction3(type_tagged, type_ptr, type_tagged, type_tagged,
function_addr, isolate_ptr, table, key);
return result;
}
TF_BUILTIN(MapGet, CollectionsBuiltinsAssembler) {
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const key = Parameter(Descriptor::kKey);
Node* const context = Parameter(Descriptor::kContext);
ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "Map.prototype.get");
Node* const table = LoadObjectField(receiver, JSMap::kTableOffset);
Return(CallGetRaw<OrderedHashMap, 2>(table, key));
}
} // namespace internal
} // namespace v8
......@@ -540,6 +540,7 @@ namespace internal {
\
/* Map */ \
TFJ(MapConstructor, 1, kIterable) \
TFJ(MapGet, 1, kKey) \
\
/* Math */ \
/* ES6 #sec-math.abs */ \
......
......@@ -529,6 +529,7 @@ bool BuiltinHasNoSideEffect(Builtins::Name id) {
case Builtins::kDatePrototypeValueOf:
// Map builtins.
case Builtins::kMapConstructor:
case Builtins::kMapGet:
// Math builtins.
case Builtins::kMathAbs:
case Builtins::kMathAcos:
......
......@@ -271,6 +271,12 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) {
Add(ExternalReference::search_string_raw<const uc16, const uc16>(isolate)
.address(),
"search_string_raw<1-byte, 2-byte>");
Add(ExternalReference::orderedhashtable_get_raw<OrderedHashMap, 2>(isolate)
.address(),
"orderedhashtable_get_raw<OrderedHashMap, 2>");
Add(ExternalReference::orderedhashtable_get_raw<OrderedHashSet, 1>(isolate)
.address(),
"orderedhashtable_get_raw<OrderedHashSet, 1>");
Add(ExternalReference::log_enter_external_function(isolate).address(),
"Logger::EnterExternal");
Add(ExternalReference::log_leave_external_function(isolate).address(),
......
......@@ -275,20 +275,6 @@ utils.InstallFunctions(GlobalSet.prototype, DONT_ENUM, [
// -------------------------------------------------------------------
// Harmony Map
function MapGet(key) {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.get', this);
}
var table = %_JSCollectionGetTable(this);
var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
var hash = GetExistingHash(key);
if (IS_UNDEFINED(hash)) return UNDEFINED;
var entry = MapFindEntry(table, numBuckets, key, hash);
if (entry === NOT_FOUND) return UNDEFINED;
return ORDERED_HASH_MAP_VALUE_AT(table, entry, numBuckets);
}
function MapSet(key, value) {
if (!IS_MAP(this)) {
......@@ -414,7 +400,6 @@ function MapForEach(f, receiver) {
// Set up the non-enumerable functions on the Map prototype object.
utils.InstallGetter(GlobalMap.prototype, "size", MapGetSize);
utils.InstallFunctions(GlobalMap.prototype, DONT_ENUM, [
"get", MapGet,
"set", MapSet,
"has", MapHas,
"delete", MapDelete,
......@@ -426,7 +411,6 @@ utils.InstallFunctions(GlobalMap.prototype, DONT_ENUM, [
// Exports
%InstallToContext([
"map_get", MapGet,
"map_set", MapSet,
"map_has", MapHas,
"map_delete", MapDelete,
......
......@@ -7087,12 +7087,6 @@ Handle<ObjectHashTable> ObjectHashTable::Shrink(
return DerivedHashTable::Shrink(table, key);
}
Object* OrderedHashMap::ValueAt(int entry) {
return get(EntryToIndex(entry) + kValueOffset);
}
template <int entrysize>
bool WeakHashTableShape<entrysize>::IsMatch(Handle<Object> key, Object* other) {
if (other->IsWeakCell()) other = WeakCell::cast(other)->value();
......
......@@ -18757,6 +18757,22 @@ bool OrderedHashTable<Derived, entrysize>::HasKey(Handle<Derived> table,
return false;
}
template <class Derived, int entrysize>
Object* OrderedHashTable<Derived, entrysize>::Get(Isolate* isolate,
Derived* table, Object* key) {
DCHECK(table->IsOrderedHashTable());
DisallowHeapAllocation no_gc;
int entry = table->KeyToFirstEntry(isolate, key);
// Walk the chain in the bucket to find the key.
while (entry != kNotFound) {
Object* candidate_key = table->KeyAt(entry);
if (candidate_key->SameValueZero(key)) {
return table->ValueAt(entry);
}
entry = table->NextChainEntry(entry);
}
return isolate->heap()->undefined_value();
}
Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
Handle<Object> key) {
......@@ -18872,6 +18888,10 @@ template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Clear(
template bool OrderedHashTable<OrderedHashSet, 1>::HasKey(
Handle<OrderedHashSet> table, Handle<Object> key);
template Object* OrderedHashTable<OrderedHashSet, 1>::Get(Isolate* isolate,
OrderedHashSet* table,
Object* key);
template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Allocate(
Isolate* isolate, int capacity, PretenureFlag pretenure);
......@@ -18887,6 +18907,9 @@ template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Clear(
template bool OrderedHashTable<OrderedHashMap, 2>::HasKey(
Handle<OrderedHashMap> table, Handle<Object> key);
template Object* OrderedHashTable<OrderedHashMap, 2>::Get(Isolate* isolate,
OrderedHashMap* table,
Object* key);
template <>
Handle<SmallOrderedHashSet>
SmallOrderedHashTable<SmallOrderedHashSet>::Allocate(Isolate* isolate,
......
......@@ -401,6 +401,10 @@ class OrderedHashTable : public FixedArray {
// Returns a true if the OrderedHashTable contains the key
static bool HasKey(Handle<Derived> table, Handle<Object> key);
// Returns a value if the OrderedHashTable contains the key,
// otherwise returns undefined.
static Object* Get(Isolate* isolate, Derived* table, Object* key);
int NumberOfElements() {
return Smi::cast(get(kNumberOfElementsIndex))->value();
}
......@@ -431,6 +435,14 @@ class OrderedHashTable : public FixedArray {
}
int KeyToFirstEntry(Isolate* isolate, Object* key) {
// This special cases for Smi, so that we avoid the HandleScope
// creation below.
if (key->IsSmi()) {
uint32_t hash =
ComputeIntegerHash(Smi::cast(key)->value(), kZeroHashSeed);
return HashToEntry(hash & Smi::kMaxValue);
}
HandleScope scope(isolate);
Object* hash = key->GetHash();
// If the object does not have an identity hash, it was never used as a key
if (hash->IsUndefined(isolate)) return kNotFound;
......@@ -448,6 +460,11 @@ class OrderedHashTable : public FixedArray {
return get(EntryToIndex(entry));
}
Object* ValueAt(int entry) {
DCHECK_LT(entry, this->UsedCapacity());
return get(EntryToIndex(entry) + Derived::kValueOffset);
}
bool IsObsolete() { return !get(kNextTableIndex)->IsSmi(); }
// The next newer table. This is only valid if the table is obsolete.
......@@ -528,14 +545,13 @@ class OrderedHashSet : public OrderedHashTable<OrderedHashSet, 1> {
Handle<Object> value);
static Handle<FixedArray> ConvertToKeysArray(Handle<OrderedHashSet> table,
GetKeysConversion convert);
static const int kValueOffset = 0;
};
class OrderedHashMap : public OrderedHashTable<OrderedHashMap, 2> {
public:
DECLARE_CAST(OrderedHashMap)
inline Object* ValueAt(int entry);
static const int kValueOffset = 1;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment