Commit c176b26f authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Lower StringEqual and friends in EffectControlLinearizer.

Turn the StringEqualStub and friends into proper TurboFan builtins,
which means that we don't need to do on-demand compilation for those
stubs, and use those to defer lowering of the StringEqual, etc.
simplified operators to effect/control linearization (i.e. move it to
the concurrent recompilation part).

BUG=v8:5428
R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2363333003
Cr-Commit-Position: refs/heads/master@{#39762}
parent c9cc3d16
This diff is collapsed.
......@@ -97,6 +97,14 @@ namespace internal {
ASM(InterruptCheck) \
ASM(StackCheck) \
\
/* String helpers */ \
TFS(StringEqual, BUILTIN, kNoExtraICState, Compare) \
TFS(StringNotEqual, BUILTIN, kNoExtraICState, Compare) \
TFS(StringLessThan, BUILTIN, kNoExtraICState, Compare) \
TFS(StringLessThanOrEqual, BUILTIN, kNoExtraICState, Compare) \
TFS(StringGreaterThan, BUILTIN, kNoExtraICState, Compare) \
TFS(StringGreaterThanOrEqual, BUILTIN, kNoExtraICState, Compare) \
\
/* Interpreter */ \
ASM(InterpreterEntryTrampoline) \
ASM(InterpreterMarkBaselineOnReturn) \
......
......@@ -410,38 +410,38 @@ Callable CodeFactory::StringCompare(Isolate* isolate, Token::Value token) {
// static
Callable CodeFactory::StringEqual(Isolate* isolate) {
StringEqualStub stub(isolate);
return make_callable(stub);
return Callable(isolate->builtins()->StringEqual(),
CompareDescriptor(isolate));
}
// static
Callable CodeFactory::StringNotEqual(Isolate* isolate) {
StringNotEqualStub stub(isolate);
return make_callable(stub);
return Callable(isolate->builtins()->StringNotEqual(),
CompareDescriptor(isolate));
}
// static
Callable CodeFactory::StringLessThan(Isolate* isolate) {
StringLessThanStub stub(isolate);
return make_callable(stub);
return Callable(isolate->builtins()->StringLessThan(),
CompareDescriptor(isolate));
}
// static
Callable CodeFactory::StringLessThanOrEqual(Isolate* isolate) {
StringLessThanOrEqualStub stub(isolate);
return make_callable(stub);
return Callable(isolate->builtins()->StringLessThanOrEqual(),
CompareDescriptor(isolate));
}
// static
Callable CodeFactory::StringGreaterThan(Isolate* isolate) {
StringGreaterThanStub stub(isolate);
return make_callable(stub);
return Callable(isolate->builtins()->StringGreaterThan(),
CompareDescriptor(isolate));
}
// static
Callable CodeFactory::StringGreaterThanOrEqual(Isolate* isolate) {
StringGreaterThanOrEqualStub stub(isolate);
return make_callable(stub);
return Callable(isolate->builtins()->StringGreaterThanOrEqual(),
CompareDescriptor(isolate));
}
// static
......
This diff is collapsed.
......@@ -148,12 +148,6 @@ class ObjectLiteral;
V(StoreScriptContextField) \
V(StrictEqual) \
V(StrictNotEqual) \
V(StringEqual) \
V(StringNotEqual) \
V(StringLessThan) \
V(StringLessThanOrEqual) \
V(StringGreaterThan) \
V(StringGreaterThanOrEqual) \
V(ToInteger) \
V(ToLength) \
V(HasProperty) \
......@@ -990,57 +984,6 @@ class StrictNotEqualStub final : public TurboFanCodeStub {
DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(StrictNotEqual, TurboFanCodeStub);
};
class StringEqualStub final : public TurboFanCodeStub {
public:
explicit StringEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(StringEqual, TurboFanCodeStub);
};
class StringNotEqualStub final : public TurboFanCodeStub {
public:
explicit StringNotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(StringNotEqual, TurboFanCodeStub);
};
class StringLessThanStub final : public TurboFanCodeStub {
public:
explicit StringLessThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(StringLessThan, TurboFanCodeStub);
};
class StringLessThanOrEqualStub final : public TurboFanCodeStub {
public:
explicit StringLessThanOrEqualStub(Isolate* isolate)
: TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(StringLessThanOrEqual, TurboFanCodeStub);
};
class StringGreaterThanStub final : public TurboFanCodeStub {
public:
explicit StringGreaterThanStub(Isolate* isolate)
: TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(StringGreaterThan, TurboFanCodeStub);
};
class StringGreaterThanOrEqualStub final : public TurboFanCodeStub {
public:
explicit StringGreaterThanOrEqualStub(Isolate* isolate)
: TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
DEFINE_TURBOFAN_CODE_STUB(StringGreaterThanOrEqual, TurboFanCodeStub);
};
class ToIntegerStub final : public TurboFanCodeStub {
public:
explicit ToIntegerStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
......
......@@ -722,6 +722,15 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kStringCharCodeAt:
state = LowerStringCharCodeAt(node, *effect, *control);
break;
case IrOpcode::kStringEqual:
state = LowerStringEqual(node, *effect, *control);
break;
case IrOpcode::kStringLessThan:
state = LowerStringLessThan(node, *effect, *control);
break;
case IrOpcode::kStringLessThanOrEqual:
state = LowerStringLessThanOrEqual(node, *effect, *control);
break;
case IrOpcode::kCheckFloat64Hole:
state = LowerCheckFloat64Hole(node, frame_state, *effect, *control);
break;
......@@ -2604,6 +2613,43 @@ EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect,
return ValueEffectControl(value, effect, control);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerStringComparison(Callable const& callable,
Node* node, Node* effect,
Node* control) {
Operator::Properties properties = Operator::kEliminatable;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
node->InsertInput(graph()->zone(), 0,
jsgraph()->HeapConstant(callable.code()));
node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant());
node->AppendInput(graph()->zone(), effect);
NodeProperties::ChangeOp(node, common()->Call(desc));
return ValueEffectControl(node, node, control);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerStringEqual(Node* node, Node* effect,
Node* control) {
return LowerStringComparison(CodeFactory::StringEqual(isolate()), node,
effect, control);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerStringLessThan(Node* node, Node* effect,
Node* control) {
return LowerStringComparison(CodeFactory::StringLessThan(isolate()), node,
effect, control);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node, Node* effect,
Node* control) {
return LowerStringComparison(CodeFactory::StringLessThanOrEqual(isolate()),
node, effect, control);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* frame_state,
Node* effect, Node* control) {
......
......@@ -12,6 +12,8 @@
namespace v8 {
namespace internal {
// Forward declarations.
class Callable;
class Zone;
namespace compiler {
......@@ -140,6 +142,11 @@ class EffectControlLinearizer {
Node* control);
ValueEffectControl LowerStringFromCharCode(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerStringEqual(Node* node, Node* effect, Node* control);
ValueEffectControl LowerStringLessThan(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerStringLessThanOrEqual(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerCheckFloat64Hole(Node* node, Node* frame_state,
Node* effect, Node* control);
ValueEffectControl LowerCheckTaggedHole(Node* node, Node* frame_state,
......@@ -179,6 +186,8 @@ class EffectControlLinearizer {
ValueEffectControl BuildCheckedHeapNumberOrOddballToFloat64(
CheckTaggedInputMode mode, Node* value, Node* frame_state, Node* effect,
Node* control);
ValueEffectControl LowerStringComparison(Callable const& callable, Node* node,
Node* effect, Node* control);
Node* ChangeInt32ToSmi(Node* value);
Node* ChangeUint32ToSmi(Node* value);
......
......@@ -622,14 +622,6 @@ PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl() {
if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED;
}
// TODO(mstarzinger): Hack to ensure that certain call descriptors are
// initialized on the main thread, since it is needed off-thread by the
// effect control linearizer.
CodeFactory::CopyFastSmiOrObjectElements(info()->isolate());
CodeFactory::GrowFastDoubleElements(info()->isolate());
CodeFactory::GrowFastSmiOrObjectElements(info()->isolate());
CodeFactory::ToNumber(info()->isolate());
linkage_ = new (&zone_) Linkage(Linkage::ComputeIncoming(&zone_, info()));
if (!pipeline_.CreateGraph()) {
......
......@@ -2040,62 +2040,11 @@ class RepresentationSelector {
}
return;
}
case IrOpcode::kStringEqual: {
VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
if (lower()) {
// StringEqual(x, y) => Call(StringEqualStub, x, y, no-context)
Operator::Properties properties =
Operator::kCommutative | Operator::kEliminatable;
Callable callable = CodeFactory::StringEqual(jsgraph_->isolate());
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
flags, properties);
node->InsertInput(jsgraph_->zone(), 0,
jsgraph_->HeapConstant(callable.code()));
node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
}
return;
}
case IrOpcode::kStringLessThan: {
VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
if (lower()) {
// StringLessThan(x, y) => Call(StringLessThanStub, x, y, no-context)
Operator::Properties properties = Operator::kEliminatable;
Callable callable = CodeFactory::StringLessThan(jsgraph_->isolate());
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
flags, properties);
node->InsertInput(jsgraph_->zone(), 0,
jsgraph_->HeapConstant(callable.code()));
node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
}
return;
}
case IrOpcode::kStringEqual:
case IrOpcode::kStringLessThan:
case IrOpcode::kStringLessThanOrEqual: {
VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
if (lower()) {
// StringLessThanOrEqual(x, y)
// => Call(StringLessThanOrEqualStub, x, y, no-context)
Operator::Properties properties = Operator::kEliminatable;
Callable callable =
CodeFactory::StringLessThanOrEqual(jsgraph_->isolate());
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
flags, properties);
node->InsertInput(jsgraph_->zone(), 0,
jsgraph_->HeapConstant(callable.code()));
node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
node->AppendInput(jsgraph_->zone(), jsgraph_->graph()->start());
NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
}
return;
return VisitBinop(node, UseInfo::AnyTagged(),
MachineRepresentation::kTagged);
}
case IrOpcode::kStringCharCodeAt: {
VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
......
......@@ -27,6 +27,7 @@
#include "src/external-reference-table.h"
#include "src/frames-inl.h"
#include "src/ic/stub-cache.h"
#include "src/interface-descriptors.h"
#include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h"
#include "src/libsampler/sampler.h"
......@@ -2390,6 +2391,12 @@ bool Isolate::Init(Deserializer* des) {
return false;
}
// Initialize the interface descriptors ahead of time.
#define INTERFACE_DESCRIPTOR(V) \
{ V##Descriptor(this); }
INTERFACE_DESCRIPTOR_LIST(INTERFACE_DESCRIPTOR)
#undef INTERFACE_DESCRIPTOR
deoptimizer_data_ = new DeoptimizerData(heap()->memory_allocator());
const bool create_heap_objects = (des == NULL);
......
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