Commit 93bcce68 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[csa] Typify dictionary related code.

Bug: v8:7754
Change-Id: I44d20d55f5da0a0f95b89a565dbe21304c6d174c
Reviewed-on: https://chromium-review.googlesource.com/1052111
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53122}
parent 8251c146
......@@ -459,8 +459,8 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral(
BIND(&if_dictionary);
{
Comment("Copy dictionary properties");
var_properties.Bind(
CopyNameDictionary(LoadSlowProperties(boilerplate), call_runtime));
var_properties.Bind(CopyNameDictionary(
CAST(LoadSlowProperties(boilerplate)), call_runtime));
// Slow objects have no in-object properties.
Goto(&done);
}
......
......@@ -484,22 +484,23 @@ class DeletePropertyBaseAssembler : public AccessorAssembler {
explicit DeletePropertyBaseAssembler(compiler::CodeAssemblerState* state)
: AccessorAssembler(state) {}
void DeleteDictionaryProperty(Node* receiver, Node* properties, Node* name,
Node* context, Label* dont_delete,
Label* notfound) {
VARIABLE(var_name_index, MachineType::PointerRepresentation());
void DeleteDictionaryProperty(TNode<Object> receiver,
TNode<NameDictionary> properties,
TNode<Name> name, TNode<Context> context,
Label* dont_delete, Label* notfound) {
TVARIABLE(IntPtrT, var_name_index);
Label dictionary_found(this, &var_name_index);
NameDictionaryLookup<NameDictionary>(properties, name, &dictionary_found,
&var_name_index, notfound);
BIND(&dictionary_found);
Node* key_index = var_name_index.value();
Node* details =
TNode<IntPtrT> key_index = var_name_index.value();
TNode<Uint32T> details =
LoadDetailsByKeyIndex<NameDictionary>(properties, key_index);
GotoIf(IsSetWord32(details, PropertyDetails::kAttributesDontDeleteMask),
dont_delete);
// Overwrite the entry itself (see NameDictionary::SetEntry).
Node* filler = TheHoleConstant();
TNode<HeapObject> filler = TheHoleConstant();
DCHECK(Heap::RootIsImmortalImmovable(Heap::kTheHoleValueRootIndex));
StoreFixedArrayElement(properties, key_index, filler, SKIP_WRITE_BARRIER);
StoreValueByKeyIndex<NameDictionary>(properties, key_index, filler,
......@@ -508,16 +509,17 @@ class DeletePropertyBaseAssembler : public AccessorAssembler {
SmiConstant(0));
// Update bookkeeping information (see NameDictionary::ElementRemoved).
Node* nof = GetNumberOfElements<NameDictionary>(properties);
Node* new_nof = SmiSub(nof, SmiConstant(1));
TNode<Smi> nof = GetNumberOfElements<NameDictionary>(properties);
TNode<Smi> new_nof = SmiSub(nof, SmiConstant(1));
SetNumberOfElements<NameDictionary>(properties, new_nof);
Node* num_deleted = GetNumberOfDeletedElements<NameDictionary>(properties);
Node* new_deleted = SmiAdd(num_deleted, SmiConstant(1));
TNode<Smi> num_deleted =
GetNumberOfDeletedElements<NameDictionary>(properties);
TNode<Smi> new_deleted = SmiAdd(num_deleted, SmiConstant(1));
SetNumberOfDeletedElements<NameDictionary>(properties, new_deleted);
// Shrink the dictionary if necessary (see NameDictionary::Shrink).
Label shrinking_done(this);
Node* capacity = GetCapacity<NameDictionary>(properties);
TNode<Smi> capacity = GetCapacity<NameDictionary>(properties);
GotoIf(SmiGreaterThan(new_nof, SmiShr(capacity, 2)), &shrinking_done);
GotoIf(SmiLessThan(new_nof, SmiConstant(16)), &shrinking_done);
CallRuntime(Runtime::kShrinkPropertyDictionary, context, receiver);
......@@ -529,10 +531,10 @@ class DeletePropertyBaseAssembler : public AccessorAssembler {
};
TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) {
Node* receiver = Parameter(Descriptor::kObject);
Node* key = Parameter(Descriptor::kKey);
Node* language_mode = Parameter(Descriptor::kLanguageMode);
Node* context = Parameter(Descriptor::kContext);
TNode<Object> receiver = CAST(Parameter(Descriptor::kObject));
TNode<Object> key = CAST(Parameter(Descriptor::kKey));
TNode<Smi> language_mode = CAST(Parameter(Descriptor::kLanguageMode));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
VARIABLE(var_index, MachineType::PointerRepresentation());
VARIABLE(var_unique, MachineRepresentation::kTagged, key);
......@@ -540,7 +542,7 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) {
if_notfound(this), slow(this);
GotoIf(TaggedIsSmi(receiver), &slow);
Node* receiver_map = LoadMap(receiver);
TNode<Map> receiver_map = LoadMap(CAST(receiver));
TNode<Int32T> instance_type = LoadMapInstanceType(receiver_map);
GotoIf(IsCustomElementsReceiverInstanceType(instance_type), &slow);
TryToName(key, &if_index, &var_index, &if_unique_name, &var_unique, &slow,
......@@ -555,7 +557,7 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) {
BIND(&if_unique_name);
{
Comment("key is unique name");
Node* unique = var_unique.value();
TNode<Name> unique = CAST(var_unique.value());
CheckForAssociatedProtector(unique, &slow);
Label dictionary(this), dont_delete(this);
......@@ -569,7 +571,8 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) {
{
InvalidateValidityCellIfPrototype(receiver_map);
Node* properties = LoadSlowProperties(receiver);
TNode<NameDictionary> properties =
CAST(LoadSlowProperties(CAST(receiver)));
DeleteDictionaryProperty(receiver, properties, unique, context,
&dont_delete, &if_notfound);
}
......
......@@ -28,8 +28,10 @@ class ObjectBuiltinsAssembler : public CodeStubAssembler {
protected:
void ReturnToStringFormat(Node* context, Node* string);
void AddToDictionaryIf(Node* condition, Node* name_dictionary,
Handle<Name> name, Node* value, Label* bailout);
void AddToDictionaryIf(TNode<BoolT> condition,
TNode<NameDictionary> name_dictionary,
Handle<Name> name, TNode<Object> value,
Label* bailout);
Node* FromPropertyDescriptor(Node* context, Node* desc);
Node* FromPropertyDetails(Node* context, Node* raw_value, Node* details,
Label* if_bailout);
......@@ -1492,10 +1494,9 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) {
args.PopAndReturn(UndefinedConstant());
}
void ObjectBuiltinsAssembler::AddToDictionaryIf(Node* condition,
Node* name_dictionary,
Handle<Name> name, Node* value,
Label* bailout) {
void ObjectBuiltinsAssembler::AddToDictionaryIf(
TNode<BoolT> condition, TNode<NameDictionary> name_dictionary,
Handle<Name> name, TNode<Object> value, Label* bailout) {
Label done(this);
GotoIfNot(condition, &done);
......@@ -1555,13 +1556,14 @@ Node* ObjectBuiltinsAssembler::FromPropertyDescriptor(Node* context,
native_context, Context::SLOW_OBJECT_WITH_OBJECT_PROTOTYPE_MAP);
// We want to preallocate the slots for value, writable, get, set,
// enumerable and configurable - a total of 6
Node* properties = AllocateNameDictionary(6);
TNode<NameDictionary> properties = AllocateNameDictionary(6);
Node* js_desc = AllocateJSObjectFromMap(map, properties);
Label bailout(this, Label::kDeferred);
Factory* factory = isolate()->factory();
Node* value = LoadObjectField(desc, PropertyDescriptorObject::kValueOffset);
TNode<Object> value =
LoadObjectField(desc, PropertyDescriptorObject::kValueOffset);
AddToDictionaryIf(IsNotTheHole(value), properties, factory->value_string(),
value, &bailout);
AddToDictionaryIf(
......@@ -1571,10 +1573,12 @@ Node* ObjectBuiltinsAssembler::FromPropertyDescriptor(Node* context,
IsSetWord32<PropertyDescriptorObject::IsWritableBit>(flags)),
&bailout);
Node* get = LoadObjectField(desc, PropertyDescriptorObject::kGetOffset);
TNode<Object> get =
LoadObjectField(desc, PropertyDescriptorObject::kGetOffset);
AddToDictionaryIf(IsNotTheHole(get), properties, factory->get_string(), get,
&bailout);
Node* set = LoadObjectField(desc, PropertyDescriptorObject::kSetOffset);
TNode<Object> set =
LoadObjectField(desc, PropertyDescriptorObject::kSetOffset);
AddToDictionaryIf(IsNotTheHole(set), properties, factory->set_string(), set,
&bailout);
......
......@@ -279,14 +279,15 @@ bool CodeStubAssembler::TryGetIntPtrOrSmiConstantValue(Node* maybe_constant,
return false;
}
Node* CodeStubAssembler::IntPtrRoundUpToPowerOfTwo32(Node* value) {
TNode<IntPtrT> CodeStubAssembler::IntPtrRoundUpToPowerOfTwo32(
TNode<IntPtrT> value) {
Comment("IntPtrRoundUpToPowerOfTwo32");
CSA_ASSERT(this, UintPtrLessThanOrEqual(value, IntPtrConstant(0x80000000u)));
value = IntPtrSub(value, IntPtrConstant(1));
value = Signed(IntPtrSub(value, IntPtrConstant(1)));
for (int i = 1; i <= 16; i *= 2) {
value = WordOr(value, WordShr(value, IntPtrConstant(i)));
value = Signed(WordOr(value, WordShr(value, IntPtrConstant(i))));
}
return IntPtrAdd(value, IntPtrConstant(1));
return Signed(IntPtrAdd(value, IntPtrConstant(1)));
}
Node* CodeStubAssembler::MatchesParameterMode(Node* value, ParameterMode mode) {
......@@ -2956,24 +2957,27 @@ TNode<String> CodeStubAssembler::NewConsString(Node* context, TNode<Smi> length,
return result.value();
}
Node* CodeStubAssembler::AllocateNameDictionary(int at_least_space_for) {
TNode<NameDictionary> CodeStubAssembler::AllocateNameDictionary(
int at_least_space_for) {
return AllocateNameDictionary(IntPtrConstant(at_least_space_for));
}
Node* CodeStubAssembler::AllocateNameDictionary(Node* at_least_space_for) {
TNode<NameDictionary> CodeStubAssembler::AllocateNameDictionary(
TNode<IntPtrT> at_least_space_for) {
CSA_ASSERT(this, UintPtrLessThanOrEqual(
at_least_space_for,
IntPtrConstant(NameDictionary::kMaxCapacity)));
Node* capacity = HashTableComputeCapacity(at_least_space_for);
TNode<IntPtrT> capacity = HashTableComputeCapacity(at_least_space_for);
return AllocateNameDictionaryWithCapacity(capacity);
}
Node* CodeStubAssembler::AllocateNameDictionaryWithCapacity(Node* capacity) {
TNode<NameDictionary> CodeStubAssembler::AllocateNameDictionaryWithCapacity(
TNode<IntPtrT> capacity) {
CSA_ASSERT(this, WordIsPowerOfTwo(capacity));
CSA_ASSERT(this, IntPtrGreaterThan(capacity, IntPtrConstant(0)));
Node* length = EntryToIndex<NameDictionary>(capacity);
Node* store_size = IntPtrAdd(TimesPointerSize(length),
IntPtrConstant(NameDictionary::kHeaderSize));
TNode<IntPtrT> length = EntryToIndex<NameDictionary>(capacity);
TNode<WordT> store_size = IntPtrAdd(
TimesPointerSize(length), IntPtrConstant(NameDictionary::kHeaderSize));
Node* result = AllocateInNewSpace(store_size);
Comment("Initialize NameDictionary");
......@@ -2983,7 +2987,7 @@ Node* CodeStubAssembler::AllocateNameDictionaryWithCapacity(Node* capacity) {
StoreObjectFieldNoWriteBarrier(result, FixedArray::kLengthOffset,
SmiFromIntPtr(length));
// Initialized HashTable fields.
Node* zero = SmiConstant(0);
TNode<Smi> zero = SmiConstant(0);
StoreFixedArrayElement(result, NameDictionary::kNumberOfElementsIndex, zero,
SKIP_WRITE_BARRIER);
StoreFixedArrayElement(result, NameDictionary::kNumberOfDeletedElementsIndex,
......@@ -2991,7 +2995,7 @@ Node* CodeStubAssembler::AllocateNameDictionaryWithCapacity(Node* capacity) {
StoreFixedArrayElement(result, NameDictionary::kCapacityIndex,
SmiTag(capacity), SKIP_WRITE_BARRIER);
// Initialize Dictionary fields.
Node* filler = UndefinedConstant();
TNode<HeapObject> filler = UndefinedConstant();
StoreFixedArrayElement(result, NameDictionary::kNextEnumerationIndexIndex,
SmiConstant(PropertyDetails::kInitialIndex),
SKIP_WRITE_BARRIER);
......@@ -3000,28 +3004,28 @@ Node* CodeStubAssembler::AllocateNameDictionaryWithCapacity(Node* capacity) {
SKIP_WRITE_BARRIER);
// Initialize NameDictionary elements.
Node* result_word = BitcastTaggedToWord(result);
Node* start_address = IntPtrAdd(
TNode<WordT> result_word = BitcastTaggedToWord(result);
TNode<WordT> start_address = IntPtrAdd(
result_word, IntPtrConstant(NameDictionary::OffsetOfElementAt(
NameDictionary::kElementsStartIndex) -
kHeapObjectTag));
Node* end_address = IntPtrAdd(
TNode<WordT> end_address = IntPtrAdd(
result_word, IntPtrSub(store_size, IntPtrConstant(kHeapObjectTag)));
StoreFieldsNoWriteBarrier(start_address, end_address, filler);
return result;
return CAST(result);
}
Node* CodeStubAssembler::CopyNameDictionary(Node* dictionary,
Label* large_object_fallback) {
CSA_ASSERT(this, IsHashTable(dictionary));
TNode<NameDictionary> CodeStubAssembler::CopyNameDictionary(
TNode<NameDictionary> dictionary, Label* large_object_fallback) {
Comment("Copy boilerplate property dict");
Node* capacity = SmiUntag(GetCapacity<NameDictionary>(dictionary));
TNode<IntPtrT> capacity = SmiUntag(GetCapacity<NameDictionary>(dictionary));
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(capacity, IntPtrConstant(0)));
GotoIf(UintPtrGreaterThan(
capacity, IntPtrConstant(NameDictionary::kMaxRegularCapacity)),
large_object_fallback);
Node* properties = AllocateNameDictionaryWithCapacity(capacity);
Node* length = SmiUntag(LoadFixedArrayBaseLength(dictionary));
TNode<NameDictionary> properties =
AllocateNameDictionaryWithCapacity(capacity);
TNode<IntPtrT> length = SmiUntag(LoadFixedArrayBaseLength(dictionary));
CopyFixedArrayElements(PACKED_ELEMENTS, dictionary, properties, length,
SKIP_WRITE_BARRIER, INTPTR_PARAMETERS);
return properties;
......@@ -6888,20 +6892,25 @@ void CodeStubAssembler::TryInternalizeString(
}
template <typename Dictionary>
Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) {
Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize));
TNode<IntPtrT> CodeStubAssembler::EntryToIndex(TNode<IntPtrT> entry,
int field_index) {
TNode<IntPtrT> entry_index =
IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize));
return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex +
field_index));
}
template Node* CodeStubAssembler::EntryToIndex<NameDictionary>(Node*, int);
template Node* CodeStubAssembler::EntryToIndex<GlobalDictionary>(Node*, int);
template Node* CodeStubAssembler::EntryToIndex<NumberDictionary>(Node*, int);
template TNode<IntPtrT> CodeStubAssembler::EntryToIndex<NameDictionary>(
TNode<IntPtrT>, int);
template TNode<IntPtrT> CodeStubAssembler::EntryToIndex<GlobalDictionary>(
TNode<IntPtrT>, int);
template TNode<IntPtrT> CodeStubAssembler::EntryToIndex<NumberDictionary>(
TNode<IntPtrT>, int);
// This must be kept in sync with HashTableBase::ComputeCapacity().
TNode<IntPtrT> CodeStubAssembler::HashTableComputeCapacity(
SloppyTNode<IntPtrT> at_least_space_for) {
Node* capacity = IntPtrRoundUpToPowerOfTwo32(
TNode<IntPtrT> at_least_space_for) {
TNode<IntPtrT> capacity = IntPtrRoundUpToPowerOfTwo32(
IntPtrAdd(at_least_space_for, WordShr(at_least_space_for, 1)));
return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity));
}
......@@ -6930,85 +6939,73 @@ TNode<IntPtrT> CodeStubAssembler::IntPtrMin(SloppyTNode<IntPtrT> left,
right);
}
template <class Dictionary>
Node* CodeStubAssembler::GetNextEnumerationIndex(Node* dictionary) {
return LoadFixedArrayElement(dictionary,
Dictionary::kNextEnumerationIndexIndex);
}
template <class Dictionary>
void CodeStubAssembler::SetNextEnumerationIndex(Node* dictionary,
Node* next_enum_index_smi) {
StoreFixedArrayElement(dictionary, Dictionary::kNextEnumerationIndexIndex,
next_enum_index_smi, SKIP_WRITE_BARRIER);
}
template <>
Node* CodeStubAssembler::LoadName<NameDictionary>(Node* key) {
TNode<HeapObject> CodeStubAssembler::LoadName<NameDictionary>(
TNode<HeapObject> key) {
CSA_ASSERT(this, Word32Or(IsTheHole(key), IsName(key)));
return key;
}
template <>
Node* CodeStubAssembler::LoadName<GlobalDictionary>(Node* key) {
CSA_ASSERT(this, IsPropertyCell(key));
CSA_ASSERT(this, IsNotTheHole(key));
return LoadObjectField(key, PropertyCell::kNameOffset);
TNode<HeapObject> CodeStubAssembler::LoadName<GlobalDictionary>(
TNode<HeapObject> key) {
TNode<PropertyCell> property_cell = CAST(key);
return CAST(LoadObjectField(property_cell, PropertyCell::kNameOffset));
}
template <typename Dictionary>
void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
Node* unique_name, Label* if_found,
Variable* var_name_index,
Label* if_not_found,
int inlined_probes,
void CodeStubAssembler::NameDictionaryLookup(
TNode<Dictionary> dictionary, TNode<Name> unique_name, Label* if_found,
TVariable<IntPtrT>* var_name_index, Label* if_not_found, int inlined_probes,
LookupMode mode) {
CSA_ASSERT(this, IsDictionary(dictionary));
static_assert(std::is_same<Dictionary, NameDictionary>::value ||
std::is_same<Dictionary, GlobalDictionary>::value,
"Unexpected NameDictionary");
DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep());
DCHECK_IMPLIES(mode == kFindInsertionIndex,
inlined_probes == 0 && if_found == nullptr);
Comment("NameDictionaryLookup");
Node* capacity = SmiUntag(GetCapacity<Dictionary>(dictionary));
Node* mask = IntPtrSub(capacity, IntPtrConstant(1));
Node* hash = ChangeUint32ToWord(LoadNameHash(unique_name));
TNode<IntPtrT> capacity = SmiUntag(GetCapacity<Dictionary>(dictionary));
TNode<WordT> mask = IntPtrSub(capacity, IntPtrConstant(1));
TNode<WordT> hash = ChangeUint32ToWord(LoadNameHash(unique_name));
// See Dictionary::FirstProbe().
Node* count = IntPtrConstant(0);
Node* entry = WordAnd(hash, mask);
TNode<IntPtrT> count = IntPtrConstant(0);
TNode<IntPtrT> entry = Signed(WordAnd(hash, mask));
Node* undefined = UndefinedConstant();
for (int i = 0; i < inlined_probes; i++) {
Node* index = EntryToIndex<Dictionary>(entry);
var_name_index->Bind(index);
TNode<IntPtrT> index = EntryToIndex<Dictionary>(entry);
*var_name_index = index;
Node* current = LoadFixedArrayElement(dictionary, index);
TNode<HeapObject> current = CAST(LoadFixedArrayElement(dictionary, index));
GotoIf(WordEqual(current, undefined), if_not_found);
current = LoadName<Dictionary>(current);
GotoIf(WordEqual(current, unique_name), if_found);
// See Dictionary::NextProbe().
count = IntPtrConstant(i + 1);
entry = WordAnd(IntPtrAdd(entry, count), mask);
entry = Signed(WordAnd(IntPtrAdd(entry, count), mask));
}
if (mode == kFindInsertionIndex) {
// Appease the variable merging algorithm for "Goto(&loop)" below.
var_name_index->Bind(IntPtrConstant(0));
*var_name_index = IntPtrConstant(0);
}
VARIABLE(var_count, MachineType::PointerRepresentation(), count);
VARIABLE(var_entry, MachineType::PointerRepresentation(), entry);
TVARIABLE(IntPtrT, var_count, count);
TVARIABLE(IntPtrT, var_entry, entry);
Variable* loop_vars[] = {&var_count, &var_entry, var_name_index};
Label loop(this, 3, loop_vars);
Goto(&loop);
BIND(&loop);
{
Node* entry = var_entry.value();
TNode<IntPtrT> entry = var_entry.value();
Node* index = EntryToIndex<Dictionary>(entry);
var_name_index->Bind(index);
TNode<IntPtrT> index = EntryToIndex<Dictionary>(entry);
*var_name_index = index;
Node* current = LoadFixedArrayElement(dictionary, index);
TNode<HeapObject> current = CAST(LoadFixedArrayElement(dictionary, index));
GotoIf(WordEqual(current, undefined), if_not_found);
if (mode == kFindExisting) {
current = LoadName<Dictionary>(current);
......@@ -7020,18 +7017,20 @@ void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
// See Dictionary::NextProbe().
Increment(&var_count);
entry = WordAnd(IntPtrAdd(entry, var_count.value()), mask);
entry = Signed(WordAnd(IntPtrAdd(entry, var_count.value()), mask));
var_entry.Bind(entry);
var_entry = entry;
Goto(&loop);
}
}
// Instantiate template methods to workaround GCC compilation issue.
template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>(
Node*, Node*, Label*, Variable*, Label*, int, LookupMode);
TNode<NameDictionary>, TNode<Name>, Label*, TVariable<IntPtrT>*, Label*,
int, LookupMode);
template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>(
Node*, Node*, Label*, Variable*, Label*, int, LookupMode);
TNode<GlobalDictionary>, TNode<Name>, Label*, TVariable<IntPtrT>*, Label*,
int, LookupMode);
Node* CodeStubAssembler::ComputeIntegerHash(Node* key) {
return ComputeIntegerHash(key, IntPtrConstant(kZeroHashSeed));
......@@ -7051,39 +7050,38 @@ Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
return Word32And(hash, Int32Constant(0x3FFFFFFF));
}
void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
Node* intptr_index,
Label* if_found,
Variable* var_entry,
Label* if_not_found) {
void CodeStubAssembler::NumberDictionaryLookup(
TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index,
Label* if_found, TVariable<IntPtrT>* var_entry, Label* if_not_found) {
CSA_ASSERT(this, IsNumberDictionary(dictionary));
DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep());
Comment("NumberDictionaryLookup");
Node* capacity = SmiUntag(GetCapacity<NumberDictionary>(dictionary));
Node* mask = IntPtrSub(capacity, IntPtrConstant(1));
TNode<IntPtrT> capacity = SmiUntag(GetCapacity<NumberDictionary>(dictionary));
TNode<WordT> mask = IntPtrSub(capacity, IntPtrConstant(1));
Node* int32_seed = HashSeed();
Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed));
TNode<Int32T> int32_seed = HashSeed();
TNode<WordT> hash =
ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed));
Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index);
// See Dictionary::FirstProbe().
Node* count = IntPtrConstant(0);
Node* entry = WordAnd(hash, mask);
TNode<IntPtrT> count = IntPtrConstant(0);
TNode<IntPtrT> entry = Signed(WordAnd(hash, mask));
Node* undefined = UndefinedConstant();
Node* the_hole = TheHoleConstant();
VARIABLE(var_count, MachineType::PointerRepresentation(), count);
TVARIABLE(IntPtrT, var_count, count);
Variable* loop_vars[] = {&var_count, var_entry};
Label loop(this, 2, loop_vars);
var_entry->Bind(entry);
*var_entry = entry;
Goto(&loop);
BIND(&loop);
{
Node* entry = var_entry->value();
TNode<IntPtrT> entry = var_entry->value();
Node* index = EntryToIndex<NumberDictionary>(entry);
TNode<IntPtrT> index = EntryToIndex<NumberDictionary>(entry);
Node* current = LoadFixedArrayElement(dictionary, index);
GotoIf(WordEqual(current, undefined), if_not_found);
Label next_probe(this);
......@@ -7108,22 +7106,24 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
BIND(&next_probe);
// See Dictionary::NextProbe().
Increment(&var_count);
entry = WordAnd(IntPtrAdd(entry, var_count.value()), mask);
entry = Signed(WordAnd(IntPtrAdd(entry, var_count.value()), mask));
var_entry->Bind(entry);
*var_entry = entry;
Goto(&loop);
}
}
template <class Dictionary>
void CodeStubAssembler::FindInsertionEntry(Node* dictionary, Node* key,
Variable* var_key_index) {
void CodeStubAssembler::FindInsertionEntry(TNode<Dictionary> dictionary,
TNode<Name> key,
TVariable<IntPtrT>* var_key_index) {
UNREACHABLE();
}
template <>
void CodeStubAssembler::FindInsertionEntry<NameDictionary>(
Node* dictionary, Node* key, Variable* var_key_index) {
TNode<NameDictionary> dictionary, TNode<Name> key,
TVariable<IntPtrT>* var_key_index) {
Label done(this);
NameDictionaryLookup<NameDictionary>(dictionary, key, nullptr, var_key_index,
&done, 0, kFindInsertionIndex);
......@@ -7131,18 +7131,17 @@ void CodeStubAssembler::FindInsertionEntry<NameDictionary>(
}
template <class Dictionary>
void CodeStubAssembler::InsertEntry(Node* dictionary, Node* key, Node* value,
Node* index, Node* enum_index) {
void CodeStubAssembler::InsertEntry(TNode<Dictionary> dictionary,
TNode<Name> key, TNode<Object> value,
TNode<IntPtrT> index,
TNode<Smi> enum_index) {
UNREACHABLE(); // Use specializations instead.
}
template <>
void CodeStubAssembler::InsertEntry<NameDictionary>(Node* dictionary,
Node* name, Node* value,
Node* index,
Node* enum_index) {
CSA_SLOW_ASSERT(this, IsDictionary(dictionary));
void CodeStubAssembler::InsertEntry<NameDictionary>(
TNode<NameDictionary> dictionary, TNode<Name> name, TNode<Object> value,
TNode<IntPtrT> index, TNode<Smi> enum_index) {
// Store name and value.
StoreFixedArrayElement(dictionary, index, name);
StoreValueByKeyIndex<NameDictionary>(dictionary, index, value);
......@@ -7153,15 +7152,14 @@ void CodeStubAssembler::InsertEntry<NameDictionary>(Node* dictionary,
SmiShl(enum_index, PropertyDetails::DictionaryStorageField::kShift);
// We OR over the actual index below, so we expect the initial value to be 0.
DCHECK_EQ(0, d.dictionary_index());
VARIABLE(var_details, MachineRepresentation::kTaggedSigned,
SmiOr(SmiConstant(d.AsSmi()), enum_index));
TVARIABLE(Smi, var_details, SmiOr(SmiConstant(d.AsSmi()), enum_index));
// Private names must be marked non-enumerable.
Label not_private(this, &var_details);
GotoIfNot(IsPrivateSymbol(name), &not_private);
Node* dont_enum =
TNode<Smi> dont_enum =
SmiShl(SmiConstant(DONT_ENUM), PropertyDetails::AttributesField::kShift);
var_details.Bind(SmiOr(var_details.value(), dont_enum));
var_details = SmiOr(var_details.value(), dont_enum);
Goto(&not_private);
BIND(&not_private);
......@@ -7171,34 +7169,33 @@ void CodeStubAssembler::InsertEntry<NameDictionary>(Node* dictionary,
}
template <>
void CodeStubAssembler::InsertEntry<GlobalDictionary>(Node* dictionary,
Node* key, Node* value,
Node* index,
Node* enum_index) {
void CodeStubAssembler::InsertEntry<GlobalDictionary>(
TNode<GlobalDictionary> dictionary, TNode<Name> key, TNode<Object> value,
TNode<IntPtrT> index, TNode<Smi> enum_index) {
UNIMPLEMENTED();
}
template <class Dictionary>
void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value,
Label* bailout) {
CSA_SLOW_ASSERT(this, IsDictionary(dictionary));
Node* capacity = GetCapacity<Dictionary>(dictionary);
Node* nof = GetNumberOfElements<Dictionary>(dictionary);
Node* new_nof = SmiAdd(nof, SmiConstant(1));
void CodeStubAssembler::Add(TNode<Dictionary> dictionary, TNode<Name> key,
TNode<Object> value, Label* bailout) {
CSA_ASSERT(this, Word32BinaryNot(IsEmptyPropertyDictionary(dictionary)));
TNode<Smi> capacity = GetCapacity<Dictionary>(dictionary);
TNode<Smi> nof = GetNumberOfElements<Dictionary>(dictionary);
TNode<Smi> new_nof = SmiAdd(nof, SmiConstant(1));
// Require 33% to still be free after adding additional_elements.
// Computing "x + (x >> 1)" on a Smi x does not return a valid Smi!
// But that's OK here because it's only used for a comparison.
Node* required_capacity_pseudo_smi = SmiAdd(new_nof, SmiShr(new_nof, 1));
TNode<Smi> required_capacity_pseudo_smi = SmiAdd(new_nof, SmiShr(new_nof, 1));
GotoIf(SmiBelow(capacity, required_capacity_pseudo_smi), bailout);
// Require rehashing if more than 50% of free elements are deleted elements.
Node* deleted = GetNumberOfDeletedElements<Dictionary>(dictionary);
TNode<Smi> deleted = GetNumberOfDeletedElements<Dictionary>(dictionary);
CSA_ASSERT(this, SmiAbove(capacity, new_nof));
Node* half_of_free_elements = SmiShr(SmiSub(capacity, new_nof), 1);
TNode<Smi> half_of_free_elements = SmiShr(SmiSub(capacity, new_nof), 1);
GotoIf(SmiAbove(deleted, half_of_free_elements), bailout);
Node* enum_index = GetNextEnumerationIndex<Dictionary>(dictionary);
Node* new_enum_index = SmiAdd(enum_index, SmiConstant(1));
Node* max_enum_index =
TNode<Smi> enum_index = GetNextEnumerationIndex<Dictionary>(dictionary);
TNode<Smi> new_enum_index = SmiAdd(enum_index, SmiConstant(1));
TNode<Smi> max_enum_index =
SmiConstant(PropertyDetails::DictionaryStorageField::kMax);
GotoIf(SmiAbove(new_enum_index, max_enum_index), bailout);
......@@ -7208,13 +7205,14 @@ void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value,
SetNextEnumerationIndex<Dictionary>(dictionary, new_enum_index);
SetNumberOfElements<Dictionary>(dictionary, new_nof);
VARIABLE(var_key_index, MachineType::PointerRepresentation());
TVARIABLE(IntPtrT, var_key_index);
FindInsertionEntry<Dictionary>(dictionary, key, &var_key_index);
InsertEntry<Dictionary>(dictionary, key, value, var_key_index.value(),
enum_index);
}
template void CodeStubAssembler::Add<NameDictionary>(Node*, Node*, Node*,
template void CodeStubAssembler::Add<NameDictionary>(TNode<NameDictionary>,
TNode<Name>, TNode<Object>,
Label*);
template <typename Array>
......@@ -7901,8 +7899,9 @@ void CodeStubAssembler::TryGetOwnProperty(
void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
SloppyTNode<Int32T> instance_type,
Node* intptr_index, Label* if_found,
Label* if_absent, Label* if_not_found,
SloppyTNode<IntPtrT> intptr_index,
Label* if_found, Label* if_absent,
Label* if_not_found,
Label* if_bailout) {
// Handle special objects in runtime.
GotoIf(IsSpecialReceiverInstanceType(instance_type), if_bailout);
......@@ -7993,8 +7992,8 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
// Negative keys must be converted to property names.
GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), if_bailout);
VARIABLE(var_entry, MachineType::PointerRepresentation());
Node* elements = LoadElements(object);
TVARIABLE(IntPtrT, var_entry);
TNode<NumberDictionary> elements = CAST(LoadElements(object));
NumberDictionaryLookup(elements, intptr_index, if_found, &var_entry,
if_not_found);
}
......
......@@ -236,7 +236,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
ParameterMode mode);
// Round the 32bits payload of the provided word up to the next power of two.
Node* IntPtrRoundUpToPowerOfTwo32(Node* value);
TNode<IntPtrT> IntPtrRoundUpToPowerOfTwo32(TNode<IntPtrT> value);
// Select the maximum of the two provided IntPtr values.
TNode<IntPtrT> IntPtrMax(SloppyTNode<IntPtrT> left,
SloppyTNode<IntPtrT> right);
......@@ -288,11 +288,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<Smi> TrySmiAdd(TNode<Smi> a, TNode<Smi> b, Label* if_overflow);
TNode<Smi> TrySmiSub(TNode<Smi> a, TNode<Smi> b, Label* if_overflow);
Node* SmiShl(Node* a, int shift) {
TNode<Smi> SmiShl(SloppyTNode<Smi> a, int shift) {
return BitcastWordToTaggedSigned(WordShl(BitcastTaggedToWord(a), shift));
}
Node* SmiShr(Node* a, int shift) {
TNode<Smi> SmiShr(SloppyTNode<Smi> a, int shift) {
return BitcastWordToTaggedSigned(
WordAnd(WordShr(BitcastTaggedToWord(a), shift),
BitcastTaggedToWord(SmiConstant(-1))));
......@@ -991,10 +991,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<String> left, TNode<String> right,
AllocationFlags flags = kNone);
Node* AllocateNameDictionary(int at_least_space_for);
Node* AllocateNameDictionary(Node* at_least_space_for);
Node* AllocateNameDictionaryWithCapacity(Node* capacity);
Node* CopyNameDictionary(Node* dictionary, Label* large_object_fallback);
TNode<NameDictionary> AllocateNameDictionary(int at_least_space_for);
TNode<NameDictionary> AllocateNameDictionary(
TNode<IntPtrT> at_least_space_for);
TNode<NameDictionary> AllocateNameDictionaryWithCapacity(
TNode<IntPtrT> capacity);
TNode<NameDictionary> CopyNameDictionary(TNode<NameDictionary> dictionary,
Label* large_object_fallback);
template <typename CollectionType>
Node* AllocateOrderedHashTable();
......@@ -1749,9 +1752,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
// Calculates array index for given dictionary entry and entry field.
// See Dictionary::EntryToIndex().
template <typename Dictionary>
Node* EntryToIndex(Node* entry, int field_index);
TNode<IntPtrT> EntryToIndex(TNode<IntPtrT> entry, int field_index);
template <typename Dictionary>
Node* EntryToIndex(Node* entry) {
TNode<IntPtrT> EntryToIndex(TNode<IntPtrT> entry) {
return EntryToIndex<Dictionary>(entry, Dictionary::kEntryKeyIndex);
}
......@@ -1801,44 +1804,52 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
}
// Calculate a valid size for the a hash table.
TNode<IntPtrT> HashTableComputeCapacity(
SloppyTNode<IntPtrT> at_least_space_for);
TNode<IntPtrT> HashTableComputeCapacity(TNode<IntPtrT> at_least_space_for);
template <class Dictionary>
Node* GetNumberOfElements(Node* dictionary) {
return LoadFixedArrayElement(dictionary,
Dictionary::kNumberOfElementsIndex);
TNode<Smi> GetNumberOfElements(TNode<Dictionary> dictionary) {
return CAST(
LoadFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex));
}
template <class Dictionary>
void SetNumberOfElements(Node* dictionary, Node* num_elements_smi) {
void SetNumberOfElements(TNode<Dictionary> dictionary,
TNode<Smi> num_elements_smi) {
StoreFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex,
num_elements_smi, SKIP_WRITE_BARRIER);
}
template <class Dictionary>
Node* GetNumberOfDeletedElements(Node* dictionary) {
return LoadFixedArrayElement(dictionary,
Dictionary::kNumberOfDeletedElementsIndex);
TNode<Smi> GetNumberOfDeletedElements(TNode<Dictionary> dictionary) {
return CAST(LoadFixedArrayElement(
dictionary, Dictionary::kNumberOfDeletedElementsIndex));
}
template <class Dictionary>
void SetNumberOfDeletedElements(Node* dictionary, Node* num_deleted_smi) {
void SetNumberOfDeletedElements(TNode<Dictionary> dictionary,
TNode<Smi> num_deleted_smi) {
StoreFixedArrayElement(dictionary,
Dictionary::kNumberOfDeletedElementsIndex,
num_deleted_smi, SKIP_WRITE_BARRIER);
}
template <class Dictionary>
Node* GetCapacity(Node* dictionary) {
return LoadFixedArrayElement(dictionary, Dictionary::kCapacityIndex);
TNode<Smi> GetCapacity(TNode<Dictionary> dictionary) {
return CAST(LoadFixedArrayElement(dictionary, Dictionary::kCapacityIndex));
}
template <class Dictionary>
Node* GetNextEnumerationIndex(Node* dictionary);
TNode<Smi> GetNextEnumerationIndex(TNode<Dictionary> dictionary) {
return CAST(LoadFixedArrayElement(dictionary,
Dictionary::kNextEnumerationIndexIndex));
}
template <class Dictionary>
void SetNextEnumerationIndex(Node* dictionary, Node* next_enum_index_smi);
void SetNextEnumerationIndex(TNode<Dictionary> dictionary,
TNode<Smi> next_enum_index_smi) {
StoreFixedArrayElement(dictionary, Dictionary::kNextEnumerationIndexIndex,
next_enum_index_smi, SKIP_WRITE_BARRIER);
}
// Looks up an entry in a NameDictionaryBase successor. If the entry is found
// control goes to {if_found} and {var_name_index} contains an index of the
......@@ -1848,11 +1859,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
enum LookupMode { kFindExisting, kFindInsertionIndex };
template <typename Dictionary>
Node* LoadName(Node* key);
TNode<HeapObject> LoadName(TNode<HeapObject> key);
template <typename Dictionary>
void NameDictionaryLookup(Node* dictionary, Node* unique_name,
Label* if_found, Variable* var_name_index,
void NameDictionaryLookup(TNode<Dictionary> dictionary,
TNode<Name> unique_name, Label* if_found,
TVariable<IntPtrT>* var_name_index,
Label* if_not_found,
int inlined_probes = kInlinedDictionaryProbes,
LookupMode mode = kFindExisting);
......@@ -1860,19 +1872,23 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* ComputeIntegerHash(Node* key);
Node* ComputeIntegerHash(Node* key, Node* seed);
void NumberDictionaryLookup(Node* dictionary, Node* intptr_index,
Label* if_found, Variable* var_entry,
void NumberDictionaryLookup(TNode<NumberDictionary> dictionary,
TNode<IntPtrT> intptr_index, Label* if_found,
TVariable<IntPtrT>* var_entry,
Label* if_not_found);
template <class Dictionary>
void FindInsertionEntry(Node* dictionary, Node* key, Variable* var_key_index);
void FindInsertionEntry(TNode<Dictionary> dictionary, TNode<Name> key,
TVariable<IntPtrT>* var_key_index);
template <class Dictionary>
void InsertEntry(Node* dictionary, Node* key, Node* value, Node* index,
Node* enum_index);
void InsertEntry(TNode<Dictionary> dictionary, TNode<Name> key,
TNode<Object> value, TNode<IntPtrT> index,
TNode<Smi> enum_index);
template <class Dictionary>
void Add(Node* dictionary, Node* key, Node* value, Label* bailout);
void Add(TNode<Dictionary> dictionary, TNode<Name> key, TNode<Object> value,
Label* bailout);
// Tries to check if {object} has own {unique_name} property.
void TryHasOwnProperty(Node* object, Node* map, Node* instance_type,
......@@ -1980,8 +1996,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
// if_absent if it's known to not exist. To if_not_found if the prototype
// chain needs to be checked. And if_bailout if the lookup is unsupported.
void TryLookupElement(Node* object, Node* map,
SloppyTNode<Int32T> instance_type, Node* intptr_index,
Label* if_found, Label* if_absent, Label* if_not_found,
SloppyTNode<Int32T> instance_type,
SloppyTNode<IntPtrT> intptr_index, Label* if_found,
Label* if_absent, Label* if_not_found,
Label* if_bailout);
// This is a type of a lookup in holder generator function. In case of a
......
......@@ -380,7 +380,7 @@ class TNode {
TNode() : node_(nullptr) {}
TNode operator=(TNode other) {
DCHECK_NULL(node_);
DCHECK_NOT_NULL(other.node_);
node_ = other.node_;
return *this;
}
......
......@@ -426,10 +426,10 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
BIND(&normal);
{
Comment("load_normal");
Node* properties = LoadSlowProperties(holder);
VARIABLE(var_name_index, MachineType::PointerRepresentation());
TNode<NameDictionary> properties = CAST(LoadSlowProperties(holder));
TVARIABLE(IntPtrT, var_name_index);
Label found(this, &var_name_index);
NameDictionaryLookup<NameDictionary>(properties, p->name, &found,
NameDictionaryLookup<NameDictionary>(properties, CAST(p->name), &found,
&var_name_index, miss);
BIND(&found);
{
......@@ -677,10 +677,11 @@ Node* AccessorAssembler::HandleProtoHandler(
CSA_ASSERT(this, Word32BinaryNot(HasInstanceType(
p->receiver, JS_GLOBAL_OBJECT_TYPE)));
Node* properties = LoadSlowProperties(p->receiver);
VARIABLE(var_name_index, MachineType::PointerRepresentation());
TNode<NameDictionary> properties =
CAST(LoadSlowProperties(p->receiver));
TVARIABLE(IntPtrT, var_name_index);
Label found(this, &var_name_index);
NameDictionaryLookup<NameDictionary>(properties, p->name, &found,
NameDictionaryLookup<NameDictionary>(properties, CAST(p->name), &found,
&var_name_index, &done);
BIND(&found);
{
......@@ -816,12 +817,12 @@ void AccessorAssembler::HandleStoreICHandlerCase(
&if_proxy);
CSA_ASSERT(this,
WordEqual(handler_kind, IntPtrConstant(StoreHandler::kNormal)));
Node* properties = LoadSlowProperties(holder);
TNode<NameDictionary> properties = CAST(LoadSlowProperties(holder));
VARIABLE(var_name_index, MachineType::PointerRepresentation());
TVARIABLE(IntPtrT, var_name_index);
Label dictionary_found(this, &var_name_index);
NameDictionaryLookup<NameDictionary>(properties, p->name, &dictionary_found,
&var_name_index, miss);
NameDictionaryLookup<NameDictionary>(
properties, CAST(p->name), &dictionary_found, &var_name_index, miss);
BIND(&dictionary_found);
{
Node* details = LoadDetailsByKeyIndex<NameDictionary>(
......@@ -1283,11 +1284,11 @@ void AccessorAssembler::HandleStoreICProtoHandler(
// case is covered above by LookupOnReceiver bit handling of the smi
// handler.
Label slow(this);
Node* receiver_map = LoadMap(p->receiver);
TNode<Map> receiver_map = LoadMap(p->receiver);
InvalidateValidityCellIfPrototype(receiver_map);
Node* properties = LoadSlowProperties(p->receiver);
Add<NameDictionary>(properties, p->name, p->value, &slow);
TNode<NameDictionary> properties = CAST(LoadSlowProperties(p->receiver));
Add<NameDictionary>(properties, CAST(p->name), p->value, &slow);
Return(p->value);
BIND(&slow);
......@@ -1695,10 +1696,11 @@ void AccessorAssembler::EmitFastElementsBoundsCheck(Node* object,
}
void AccessorAssembler::EmitElementLoad(
Node* object, Node* elements, Node* elements_kind, Node* intptr_index,
Node* is_jsarray_condition, Label* if_hole, Label* rebox_double,
Variable* var_double_value, Label* unimplemented_elements_kind,
Label* out_of_bounds, Label* miss, ExitPoint* exit_point) {
Node* object, Node* elements, Node* elements_kind,
SloppyTNode<IntPtrT> intptr_index, Node* is_jsarray_condition,
Label* if_hole, Label* rebox_double, Variable* var_double_value,
Label* unimplemented_elements_kind, Label* out_of_bounds, Label* miss,
ExitPoint* exit_point) {
Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this),
if_fast_double(this), if_fast_holey_double(this), if_nonfast(this),
if_dictionary(this);
......@@ -1775,13 +1777,13 @@ void AccessorAssembler::EmitElementLoad(
{
Comment("dictionary elements");
GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), out_of_bounds);
VARIABLE(var_entry, MachineType::PointerRepresentation());
TVARIABLE(IntPtrT, var_entry);
Label if_found(this);
NumberDictionaryLookup(elements, intptr_index, &if_found, &var_entry,
NumberDictionaryLookup(CAST(elements), intptr_index, &if_found, &var_entry,
if_hole);
BIND(&if_found);
// Check that the value is a data property.
Node* index = EntryToIndex<NumberDictionary>(var_entry.value());
TNode<IntPtrT> index = EntryToIndex<NumberDictionary>(var_entry.value());
Node* details = LoadDetailsByKeyIndex<NumberDictionary>(elements, index);
Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
// TODO(jkummerow): Support accessors without missing?
......@@ -1896,12 +1898,13 @@ void AccessorAssembler::EmitElementLoad(
}
}
void AccessorAssembler::NameDictionaryNegativeLookup(Node* object, Node* name,
void AccessorAssembler::NameDictionaryNegativeLookup(Node* object,
SloppyTNode<Name> name,
Label* miss) {
CSA_ASSERT(this, IsDictionaryMap(LoadMap(object)));
Node* properties = LoadSlowProperties(object);
TNode<NameDictionary> properties = CAST(LoadSlowProperties(object));
// Ensure the property does not exist in a dictionary-mode object.
VARIABLE(var_name_index, MachineType::PointerRepresentation());
TVARIABLE(IntPtrT, var_name_index);
Label done(this);
NameDictionaryLookup<NameDictionary>(properties, name, miss, &var_name_index,
&done);
......@@ -2103,11 +2106,11 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map,
// We checked for LAST_CUSTOM_ELEMENTS_RECEIVER before, which rules out
// seeing global objects here (which would need special handling).
VARIABLE(var_name_index, MachineType::PointerRepresentation());
TVARIABLE(IntPtrT, var_name_index);
Label dictionary_found(this, &var_name_index);
Node* properties = LoadSlowProperties(receiver);
NameDictionaryLookup<NameDictionary>(properties, p->name, &dictionary_found,
&var_name_index,
TNode<NameDictionary> properties = CAST(LoadSlowProperties(receiver));
NameDictionaryLookup<NameDictionary>(properties, CAST(p->name),
&dictionary_found, &var_name_index,
&lookup_prototype_chain);
BIND(&dictionary_found);
{
......@@ -2910,7 +2913,7 @@ void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) {
Signed(DecodeWord<FeedbackNexus::SlotIndexBits>(lexical_handler));
TNode<Context> script_context =
LoadScriptContext(CAST(pp->context), context_index);
StoreContextElement(script_context, slot_index, CAST(pp->value));
StoreContextElement(script_context, slot_index, pp->value);
Return(pp->value);
}
}
......
......@@ -93,11 +93,11 @@ class AccessorAssembler : public CodeStubAssembler {
protected:
struct StoreICParameters : public LoadICParameters {
StoreICParameters(Node* context, Node* receiver, Node* name, Node* value,
Node* slot, Node* vector)
StoreICParameters(Node* context, Node* receiver, Node* name,
SloppyTNode<Object> value, Node* slot, Node* vector)
: LoadICParameters(context, receiver, name, slot, vector),
value(value) {}
Node* value;
SloppyTNode<Object> value;
};
enum class ICMode { kNonGlobalIC, kGlobalIC };
......@@ -265,11 +265,13 @@ class AccessorAssembler : public CodeStubAssembler {
Node* intptr_index,
Node* is_jsarray_condition, Label* miss);
void EmitElementLoad(Node* object, Node* elements, Node* elements_kind,
Node* key, Node* is_jsarray_condition, Label* if_hole,
Label* rebox_double, Variable* var_double_value,
SloppyTNode<IntPtrT> key, Node* is_jsarray_condition,
Label* if_hole, Label* rebox_double,
Variable* var_double_value,
Label* unimplemented_elements_kind, Label* out_of_bounds,
Label* miss, ExitPoint* exit_point);
void NameDictionaryNegativeLookup(Node* object, Node* name, Label* miss);
void NameDictionaryNegativeLookup(Node* object, SloppyTNode<Name> name,
Label* miss);
// Stub cache access helpers.
......
......@@ -759,15 +759,16 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
// We checked for LAST_CUSTOM_ELEMENTS_RECEIVER before, which rules out
// seeing global objects here (which would need special handling).
VARIABLE(var_name_index, MachineType::PointerRepresentation());
TVARIABLE(IntPtrT, var_name_index);
Label dictionary_found(this, &var_name_index), not_found(this);
TNode<NameDictionary> properties = CAST(LoadSlowProperties(CAST(receiver)));
NameDictionaryLookup<NameDictionary>(properties, p->name, &dictionary_found,
&var_name_index, &not_found);
NameDictionaryLookup<NameDictionary>(properties, CAST(p->name),
&dictionary_found, &var_name_index,
&not_found);
BIND(&dictionary_found);
{
Label overwrite(this);
Node* details = LoadDetailsByKeyIndex<NameDictionary>(
TNode<Uint32T> details = LoadDetailsByKeyIndex<NameDictionary>(
properties, var_name_index.value());
JumpIfDataProperty(details, &overwrite, &readonly);
......@@ -800,7 +801,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
&readonly, slow);
Label add_dictionary_property_slow(this);
InvalidateValidityCellIfPrototype(receiver_map, bitfield2);
Add<NameDictionary>(properties, p->name, p->value,
Add<NameDictionary>(properties, CAST(p->name), p->value,
&add_dictionary_property_slow);
exit_point->Return(p->value);
......
......@@ -25,8 +25,10 @@ namespace compiler {
namespace {
typedef CodeAssemblerLabel Label;
typedef CodeAssemblerVariable Variable;
using Label = CodeAssemblerLabel;
using Variable = CodeAssemblerVariable;
template <class T>
using TVariable = TypedCodeAssemblerVariable<T>;
Handle<String> MakeString(const char* str) {
Isolate* isolate = CcTest::i_isolate();
......@@ -545,8 +547,8 @@ void TestEntryToIndex() {
CodeAssemblerTester asm_tester(isolate, kNumParams);
CodeStubAssembler m(asm_tester.state());
{
Node* entry = m.SmiUntag(m.Parameter(0));
Node* result = m.EntryToIndex<Dictionary>(entry);
TNode<IntPtrT> entry = m.SmiUntag(m.Parameter(0));
TNode<IntPtrT> result = m.EntryToIndex<Dictionary>(entry);
m.Return(m.SmiTag(result));
}
......@@ -578,14 +580,14 @@ void TestNameDictionaryLookup() {
enum Result { kFound, kNotFound };
{
Node* dictionary = m.Parameter(0);
Node* unique_name = m.Parameter(1);
Node* expected_result = m.Parameter(2);
Node* expected_arg = m.Parameter(3);
TNode<Dictionary> dictionary = m.CAST(m.Parameter(0));
TNode<Name> unique_name = m.CAST(m.Parameter(1));
TNode<Smi> expected_result = m.CAST(m.Parameter(2));
TNode<Object> expected_arg = m.CAST(m.Parameter(3));
Label passed(&m), failed(&m);
Label if_found(&m), if_not_found(&m);
Variable var_name_index(&m, MachineType::PointerRepresentation());
TVariable<IntPtrT> var_name_index(&m);
m.NameDictionaryLookup<Dictionary>(dictionary, unique_name, &if_found,
&var_name_index, &if_not_found);
......@@ -593,7 +595,8 @@ void TestNameDictionaryLookup() {
m.GotoIfNot(
m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
&failed);
m.Branch(m.WordEqual(m.SmiUntag(expected_arg), var_name_index.value()),
m.Branch(
m.WordEqual(m.SmiUntag(m.CAST(expected_arg)), var_name_index.value()),
&passed, &failed);
m.BIND(&if_not_found);
......@@ -679,14 +682,14 @@ TEST(NumberDictionaryLookup) {
enum Result { kFound, kNotFound };
{
Node* dictionary = m.Parameter(0);
Node* key = m.SmiUntag(m.Parameter(1));
Node* expected_result = m.Parameter(2);
Node* expected_arg = m.Parameter(3);
TNode<NumberDictionary> dictionary = m.CAST(m.Parameter(0));
TNode<IntPtrT> key = m.SmiUntag(m.Parameter(1));
TNode<Smi> expected_result = m.CAST(m.Parameter(2));
TNode<Object> expected_arg = m.CAST(m.Parameter(3));
Label passed(&m), failed(&m);
Label if_found(&m), if_not_found(&m);
Variable var_entry(&m, MachineType::PointerRepresentation());
TVariable<IntPtrT> var_entry(&m);
m.NumberDictionaryLookup(dictionary, key, &if_found, &var_entry,
&if_not_found);
......@@ -694,8 +697,8 @@ TEST(NumberDictionaryLookup) {
m.GotoIfNot(
m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
&failed);
m.Branch(m.WordEqual(m.SmiUntag(expected_arg), var_entry.value()), &passed,
&failed);
m.Branch(m.WordEqual(m.SmiUntag(m.CAST(expected_arg)), var_entry.value()),
&passed, &failed);
m.BIND(&if_not_found);
m.Branch(
......
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