Commit 71dfcbac authored by jkummerow's avatar jkummerow Committed by Commit bot

[stubs] Consolidate TryToName implementation

This extends TryToName by HeapNumber-to-intptr support and cached array
index retrieval from non-internalized strings, and uses it in the
KeyedLoadIC_Generic stub.

Bonus: avoid needless movsxlq on x64 in LoadFixed{,Double}ArrayElement
helpers by introducing INTPTR_PARAMETER mode.

Review-Url: https://codereview.chromium.org/2277363002
Cr-Commit-Position: refs/heads/master@{#39217}
parent b28b7e13
......@@ -35,7 +35,7 @@ void Builtins::Generate_ObjectHasOwnProperty(CodeStubAssembler* assembler) {
Node* map = assembler->LoadMap(object);
Node* instance_type = assembler->LoadMapInstanceType(map);
Variable var_index(assembler, MachineRepresentation::kWord32);
Variable var_index(assembler, MachineType::PointerRepresentation());
Label keyisindex(assembler), if_iskeyunique(assembler);
assembler->TryToName(key, &keyisindex, &var_index, &if_iskeyunique,
......
This diff is collapsed.
......@@ -46,7 +46,7 @@ class CodeStubAssembler : public compiler::CodeAssembler {
typedef base::Flags<AllocationFlag> AllocationFlags;
enum ParameterMode { INTEGER_PARAMETERS, SMI_PARAMETERS };
enum ParameterMode { INTEGER_PARAMETERS, SMI_PARAMETERS, INTPTR_PARAMETERS };
compiler::Node* BooleanMapConstant();
compiler::Node* EmptyStringConstant();
......@@ -399,9 +399,9 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* ComputeIntegerHash(compiler::Node* key, compiler::Node* seed);
template <typename Dictionary>
void NumberDictionaryLookup(compiler::Node* dictionary, compiler::Node* key,
Label* if_found, Variable* var_entry,
Label* if_not_found);
void NumberDictionaryLookup(compiler::Node* dictionary,
compiler::Node* intptr_index, Label* if_found,
Variable* var_entry, Label* if_not_found);
// Tries to check if {object} has own {unique_name} property.
void TryHasOwnProperty(compiler::Node* object, compiler::Node* map,
......@@ -454,9 +454,9 @@ class CodeStubAssembler : public compiler::CodeAssembler {
Label* if_not_found, Label* if_bailout);
void TryLookupElement(compiler::Node* object, compiler::Node* map,
compiler::Node* instance_type, compiler::Node* index,
Label* if_found, Label* if_not_found,
Label* if_bailout);
compiler::Node* instance_type,
compiler::Node* intptr_index, Label* if_found,
Label* if_not_found, Label* if_bailout);
// This is a type of a lookup in holder generator function. In case of a
// property lookup the {key} is guaranteed to be a unique name and in case of
......@@ -579,7 +579,7 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* TryToIntptr(compiler::Node* key, Label* miss);
void EmitFastElementsBoundsCheck(compiler::Node* object,
compiler::Node* elements,
compiler::Node* intptr_key,
compiler::Node* intptr_index,
compiler::Node* is_jsarray_condition,
Label* miss);
void EmitElementLoad(compiler::Node* object, compiler::Node* elements,
......
......@@ -234,6 +234,13 @@ Node* CodeAssembler::ChangeInt32ToIntPtr(Node* value) {
return value;
}
Node* CodeAssembler::RoundIntPtrToFloat64(Node* value) {
if (raw_assembler_->machine()->Is64()) {
return raw_assembler_->RoundInt64ToFloat64(value);
}
return raw_assembler_->ChangeInt32ToFloat64(value);
}
#define DEFINE_CODE_ASSEMBLER_UNARY_OP(name) \
Node* CodeAssembler::name(Node* a) { return raw_assembler_->name(a); }
CODE_ASSEMBLER_UNARY_OP_LIST(DEFINE_CODE_ASSEMBLER_UNARY_OP)
......
......@@ -283,6 +283,10 @@ class CodeAssembler {
CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
#undef DECLARE_CODE_ASSEMBLER_UNARY_OP
// Changes an intptr_t to a double, e.g. for storing an element index
// outside Smi range in a HeapNumber. Lossless on 32-bit,
// rounds on 64-bit (which doesn't affect valid element indices).
Node* RoundIntPtrToFloat64(Node* value);
// No-op on 32-bit, otherwise zero extend.
Node* ChangeUint32ToWord(Node* value);
// No-op on 32-bit, otherwise sign extend.
......
......@@ -135,7 +135,7 @@ TEST(TryToName) {
Label passed(&m), failed(&m);
Label if_keyisindex(&m), if_keyisunique(&m), if_bailout(&m);
Variable var_index(&m, MachineRepresentation::kWord32);
Variable var_index(&m, MachineType::PointerRepresentation());
m.TryToName(key, &if_keyisindex, &var_index, &if_keyisunique, &if_bailout);
......@@ -143,8 +143,8 @@ TEST(TryToName) {
m.GotoUnless(
m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kKeyIsIndex))),
&failed);
m.Branch(m.Word32Equal(m.SmiToWord32(expected_arg), var_index.value()),
&passed, &failed);
m.Branch(m.WordEqual(m.SmiUntag(expected_arg), var_index.value()), &passed,
&failed);
m.Bind(&if_keyisunique);
m.GotoUnless(
......@@ -184,9 +184,17 @@ TEST(TryToName) {
}
{
// TryToName(<negative smi>) => bailout.
// TryToName(<negative smi>) => if_keyisindex: smi value.
// A subsequent bounds check needs to take care of this case.
Handle<Object> key(Smi::FromInt(-1), isolate);
ft.CheckTrue(key, expect_bailout);
ft.CheckTrue(key, expect_index, key);
}
{
// TryToName(<heap number with int value>) => if_keyisindex: number.
Handle<Object> key(isolate->factory()->NewHeapNumber(153));
Handle<Object> index(Smi::FromInt(153), isolate);
ft.CheckTrue(key, expect_index, index);
}
{
......@@ -208,6 +216,31 @@ TEST(TryToName) {
ft.CheckTrue(key, expect_index, index);
}
{
// TryToName(<internalized uncacheable number string>) => bailout
Handle<Object> key =
isolate->factory()->InternalizeUtf8String("4294967294");
ft.CheckTrue(key, expect_bailout);
}
{
// TryToName(<non-internalized number string>) => if_keyisindex: number.
Handle<String> key = isolate->factory()->NewStringFromAsciiChecked("153");
uint32_t dummy;
CHECK(key->AsArrayIndex(&dummy));
CHECK(key->HasHashCode());
CHECK(!key->IsInternalizedString());
Handle<Object> index(Smi::FromInt(153), isolate);
ft.CheckTrue(key, expect_index, index);
}
{
// TryToName(<number string without cached index>) => bailout.
Handle<String> key = isolate->factory()->NewStringFromAsciiChecked("153");
CHECK(!key->HasHashCode());
ft.CheckTrue(key, expect_bailout);
}
{
// TryToName(<non-internalized string>) => bailout.
Handle<Object> key = isolate->factory()->NewStringFromAsciiChecked("test");
......
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