[stubs] Port NumberToStringSub to Turbofan
In the process, also fix a merge hiccup that clobbered https://codereview.chromium.org/2003663002/ back in May. BUG=chromium:608675 LOG=N Review-Url: https://codereview.chromium.org/2397223002 Cr-Commit-Position: refs/heads/master@{#40085}
This commit is contained in:
parent
c64288d9db
commit
e0741946cb
@ -2834,6 +2834,85 @@ Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) {
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::NumberToString(compiler::Node* context,
|
||||
compiler::Node* argument) {
|
||||
Variable result(this, MachineRepresentation::kTagged);
|
||||
Label runtime(this, Label::kDeferred);
|
||||
Label smi(this);
|
||||
Label done(this, &result);
|
||||
|
||||
// Load the number string cache.
|
||||
Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex);
|
||||
|
||||
// Make the hash mask from the length of the number string cache. It
|
||||
// contains two elements (number and string) for each cache entry.
|
||||
Node* mask = LoadFixedArrayBaseLength(number_string_cache);
|
||||
Node* one = IntPtrConstant(1);
|
||||
mask = IntPtrSub(mask, one);
|
||||
|
||||
GotoIf(WordIsSmi(argument), &smi);
|
||||
|
||||
// Argument isn't smi, check to see if it's a heap-number.
|
||||
Node* map = LoadMap(argument);
|
||||
GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime);
|
||||
|
||||
// Make a hash from the two 32-bit values of the double.
|
||||
Node* low =
|
||||
LoadObjectField(argument, HeapNumber::kValueOffset, MachineType::Int32());
|
||||
Node* high = LoadObjectField(argument, HeapNumber::kValueOffset + kIntSize,
|
||||
MachineType::Int32());
|
||||
Node* hash = Word32Xor(low, high);
|
||||
if (Is64()) hash = ChangeInt32ToInt64(hash);
|
||||
hash = WordShl(hash, one);
|
||||
Node* index = WordAnd(hash, SmiToWord(mask));
|
||||
|
||||
// Cache entry's key must be a heap number
|
||||
Node* number_key =
|
||||
LoadFixedArrayElement(number_string_cache, index, 0, INTPTR_PARAMETERS);
|
||||
GotoIf(WordIsSmi(number_key), &runtime);
|
||||
map = LoadMap(number_key);
|
||||
GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime);
|
||||
|
||||
// Cache entry's key must match the heap number value we're looking for.
|
||||
Node* low_compare = LoadObjectField(number_key, HeapNumber::kValueOffset,
|
||||
MachineType::Int32());
|
||||
Node* high_compare = LoadObjectField(
|
||||
number_key, HeapNumber::kValueOffset + kIntSize, MachineType::Int32());
|
||||
GotoUnless(WordEqual(low, low_compare), &runtime);
|
||||
GotoUnless(WordEqual(high, high_compare), &runtime);
|
||||
|
||||
// Heap number match, return value fro cache entry.
|
||||
IncrementCounter(isolate()->counters()->number_to_string_native(), 1);
|
||||
result.Bind(LoadFixedArrayElement(number_string_cache, index, kPointerSize,
|
||||
INTPTR_PARAMETERS));
|
||||
Goto(&done);
|
||||
|
||||
Bind(&runtime);
|
||||
{
|
||||
// No cache entry, go to the runtime.
|
||||
result.Bind(CallRuntime(Runtime::kNumberToString, context, argument));
|
||||
}
|
||||
Goto(&done);
|
||||
|
||||
Bind(&smi);
|
||||
{
|
||||
// Load the smi key, make sure it matches the smi we're looking for.
|
||||
Node* smi_index = WordAnd(WordShl(argument, one), mask);
|
||||
Node* smi_key = LoadFixedArrayElement(number_string_cache, smi_index, 0,
|
||||
SMI_PARAMETERS);
|
||||
GotoIf(WordNotEqual(smi_key, argument), &runtime);
|
||||
|
||||
// Smi match, return value from cache entry.
|
||||
IncrementCounter(isolate()->counters()->number_to_string_native(), 1);
|
||||
result.Bind(LoadFixedArrayElement(number_string_cache, smi_index,
|
||||
kPointerSize, SMI_PARAMETERS));
|
||||
Goto(&done);
|
||||
}
|
||||
|
||||
Bind(&done);
|
||||
return result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::ToName(Node* context, Node* value) {
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef CodeStubAssembler::Variable Variable;
|
||||
|
@ -521,6 +521,8 @@ class CodeStubAssembler : public compiler::CodeAssembler {
|
||||
// Convert a String to a Number.
|
||||
compiler::Node* StringToNumber(compiler::Node* context,
|
||||
compiler::Node* input);
|
||||
compiler::Node* NumberToString(compiler::Node* context,
|
||||
compiler::Node* input);
|
||||
// Convert an object to a name.
|
||||
compiler::Node* ToName(compiler::Node* context, compiler::Node* input);
|
||||
// Convert a Non-Number object to a Number.
|
||||
|
@ -328,18 +328,6 @@ static Handle<Code> DoGenerateCode(Stub* stub) {
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
|
||||
info()->MarkAsSavesCallerDoubles();
|
||||
HValue* number = GetParameter(Descriptor::kArgument);
|
||||
return BuildNumberToString(number, AstType::Number());
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> NumberToStringStub::GenerateCode() {
|
||||
return DoGenerateCode(this);
|
||||
}
|
||||
|
||||
HValue* CodeStubGraphBuilderBase::BuildPushElement(HValue* object, HValue* argc,
|
||||
HValue* argument_elements,
|
||||
ElementsKind kind) {
|
||||
|
@ -1466,6 +1466,13 @@ compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
|
||||
return result_var.value();
|
||||
}
|
||||
|
||||
void NumberToStringStub::GenerateAssembly(CodeStubAssembler* assembler) const {
|
||||
typedef compiler::Node Node;
|
||||
Node* argument = assembler->Parameter(Descriptor::kArgument);
|
||||
Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
assembler->Return(assembler->NumberToString(context, argument));
|
||||
}
|
||||
|
||||
// static
|
||||
compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
|
||||
compiler::Node* value,
|
||||
@ -2046,12 +2053,6 @@ CallInterfaceDescriptor HandlerStub::GetCallInterfaceDescriptor() const {
|
||||
}
|
||||
|
||||
|
||||
void NumberToStringStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
|
||||
descriptor->Initialize(
|
||||
Runtime::FunctionForId(Runtime::kNumberToString)->entry);
|
||||
descriptor->SetMissHandler(Runtime::kNumberToString);
|
||||
}
|
||||
|
||||
void RegExpConstructResultStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
descriptor->Initialize(
|
||||
|
@ -66,7 +66,6 @@ class ObjectLiteral;
|
||||
V(KeyedStoreICTrampoline) \
|
||||
V(StoreICTrampoline) \
|
||||
/* --- HydrogenCodeStubs --- */ \
|
||||
V(NumberToString) \
|
||||
V(StringAdd) \
|
||||
/* These builtins w/ JS linkage are */ \
|
||||
/* just fast-cases of C++ builtins. They */ \
|
||||
@ -127,6 +126,7 @@ class ObjectLiteral;
|
||||
V(KeyedStoreSloppyArguments) \
|
||||
V(LoadScriptContextField) \
|
||||
V(StoreScriptContextField) \
|
||||
V(NumberToString) \
|
||||
V(GetProperty) \
|
||||
V(LoadICTF) \
|
||||
V(KeyedLoadICTF) \
|
||||
@ -847,13 +847,12 @@ enum StringAddFlags {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const StringAddFlags& flags);
|
||||
|
||||
|
||||
class NumberToStringStub final : public HydrogenCodeStub {
|
||||
class NumberToStringStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit NumberToStringStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
|
||||
explicit NumberToStringStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
|
||||
DEFINE_HYDROGEN_CODE_STUB(NumberToString, HydrogenCodeStub);
|
||||
DEFINE_TURBOFAN_CODE_STUB(NumberToString, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class FastNewClosureStub : public TurboFanCodeStub {
|
||||
|
@ -344,7 +344,7 @@ void Schedule::EnsureSplitEdgeForm(BasicBlock* block) {
|
||||
split_edge_block->set_control(BasicBlock::kGoto);
|
||||
split_edge_block->successors().push_back(block);
|
||||
split_edge_block->predecessors().push_back(pred);
|
||||
split_edge_block->set_deferred(pred->deferred());
|
||||
split_edge_block->set_deferred(block->deferred());
|
||||
*current_pred = split_edge_block;
|
||||
// Find a corresponding successor in the previous block, replace it
|
||||
// with the split edge block... but only do it once, since we only
|
||||
|
Loading…
Reference in New Issue
Block a user