Commit 64351075 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Move Date.now/Date.p.getTime to JSCallReducer

This CL also introduces an effect dependent simplified operator
DateNow and associated lowerings.

Bug: v8:7340, v8:7250
Change-Id: Icd4a8c3c45a8dbe7ef490fc3ee68c0c68bbed011
Reviewed-on: https://chromium-review.googlesource.com/1024836
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52782}
parent 068e40d5
...@@ -976,6 +976,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, ...@@ -976,6 +976,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
return false; return false;
} }
break; break;
case IrOpcode::kDateNow:
result = LowerDateNow(node);
break;
default: default:
return false; return false;
} }
...@@ -4670,6 +4673,16 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key( ...@@ -4670,6 +4673,16 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key(
return done.PhiAt(0); return done.PhiAt(0);
} }
Node* EffectControlLinearizer::LowerDateNow(Node* node) {
Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow;
Runtime::FunctionId id = Runtime::kDateCurrentTime;
auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
graph()->zone(), id, 0, properties, CallDescriptor::kNoFlags);
return __ Call(call_descriptor, __ CEntryStubConstant(1),
__ ExternalConstant(ExternalReference::Create(id)),
__ Int32Constant(0), __ NoContextConstant());
}
#undef __ #undef __
Factory* EffectControlLinearizer::factory() const { Factory* EffectControlLinearizer::factory() const {
......
...@@ -158,6 +158,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer { ...@@ -158,6 +158,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
void LowerTransitionAndStoreNonNumberElement(Node* node); void LowerTransitionAndStoreNonNumberElement(Node* node);
void LowerRuntimeAbort(Node* node); void LowerRuntimeAbort(Node* node);
Node* LowerConvertReceiver(Node* node); Node* LowerConvertReceiver(Node* node);
Node* LowerDateNow(Node* node);
// Lowering of optional operators. // Lowering of optional operators.
Maybe<Node*> LowerFloat64RoundUp(Node* node); Maybe<Node*> LowerFloat64RoundUp(Node* node);
......
...@@ -115,29 +115,6 @@ JSBuiltinReducer::JSBuiltinReducer(Editor* editor, JSGraph* jsgraph, ...@@ -115,29 +115,6 @@ JSBuiltinReducer::JSBuiltinReducer(Editor* editor, JSGraph* jsgraph,
native_context_(native_context), native_context_(native_context),
type_cache_(TypeCache::Get()) {} type_cache_(TypeCache::Get()) {}
// ES6 section 20.3.3.1 Date.now ( )
Reduction JSBuiltinReducer::ReduceDateNow(Node* node) {
NodeProperties::RemoveValueInputs(node);
NodeProperties::ChangeOp(
node, javascript()->CallRuntime(Runtime::kDateCurrentTime));
return Changed(node);
}
// ES6 section 20.3.4.10 Date.prototype.getTime ( )
Reduction JSBuiltinReducer::ReduceDateGetTime(Node* node) {
Node* receiver = NodeProperties::GetValueInput(node, 1);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
if (NodeProperties::HasInstanceTypeWitness(receiver, effect, JS_DATE_TYPE)) {
Node* value = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForJSDateValue()), receiver,
effect, control);
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
return NoChange();
}
// ES6 section 20.1.2.13 Number.parseInt ( string, radix ) // ES6 section 20.1.2.13 Number.parseInt ( string, radix )
Reduction JSBuiltinReducer::ReduceNumberParseInt(Node* node) { Reduction JSBuiltinReducer::ReduceNumberParseInt(Node* node) {
JSCallReduction r(node); JSCallReduction r(node);
...@@ -162,10 +139,6 @@ Reduction JSBuiltinReducer::Reduce(Node* node) { ...@@ -162,10 +139,6 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
if (!r.HasBuiltinFunctionId()) return NoChange(); if (!r.HasBuiltinFunctionId()) return NoChange();
if (!r.BuiltinCanBeInlined()) return NoChange(); if (!r.BuiltinCanBeInlined()) return NoChange();
switch (r.GetBuiltinFunctionId()) { switch (r.GetBuiltinFunctionId()) {
case kDateNow:
return ReduceDateNow(node);
case kDateGetTime:
return ReduceDateGetTime(node);
case kNumberParseInt: case kNumberParseInt:
reduction = ReduceNumberParseInt(node); reduction = ReduceNumberParseInt(node);
break; break;
......
...@@ -39,8 +39,6 @@ class V8_EXPORT_PRIVATE JSBuiltinReducer final ...@@ -39,8 +39,6 @@ class V8_EXPORT_PRIVATE JSBuiltinReducer final
Reduction Reduce(Node* node) final; Reduction Reduce(Node* node) final;
private: private:
Reduction ReduceDateNow(Node* node);
Reduction ReduceDateGetTime(Node* node);
Reduction ReduceNumberParseInt(Node* node); Reduction ReduceNumberParseInt(Node* node);
Node* ToNumber(Node* value); Node* ToNumber(Node* value);
Node* ToUint32(Node* value); Node* ToUint32(Node* value);
......
...@@ -3580,6 +3580,10 @@ Reduction JSCallReducer::ReduceJSCall(Node* node, ...@@ -3580,6 +3580,10 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
return ReduceCollectionIteratorPrototypeNext( return ReduceCollectionIteratorPrototypeNext(
node, OrderedHashSet::kEntrySize, factory()->empty_ordered_hash_set(), node, OrderedHashSet::kEntrySize, factory()->empty_ordered_hash_set(),
FIRST_SET_ITERATOR_TYPE, LAST_SET_ITERATOR_TYPE); FIRST_SET_ITERATOR_TYPE, LAST_SET_ITERATOR_TYPE);
case Builtins::kDatePrototypeGetTime:
return ReduceDatePrototypeGetTime(node);
case Builtins::kDateNow:
return ReduceDateNow(node);
default: default:
break; break;
} }
...@@ -6669,6 +6673,31 @@ Reduction JSCallReducer::ReduceGlobalIsNaN(Node* node) { ...@@ -6669,6 +6673,31 @@ Reduction JSCallReducer::ReduceGlobalIsNaN(Node* node) {
return Replace(value); return Replace(value);
} }
// ES6 section 20.3.4.10 Date.prototype.getTime ( )
Reduction JSCallReducer::ReduceDatePrototypeGetTime(Node* node) {
Node* receiver = NodeProperties::GetValueInput(node, 1);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
if (NodeProperties::HasInstanceTypeWitness(receiver, effect, JS_DATE_TYPE)) {
Node* value = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForJSDateValue()), receiver,
effect, control);
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
return NoChange();
}
// ES6 section 20.3.3.1 Date.now ( )
Reduction JSCallReducer::ReduceDateNow(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* value = effect =
graph()->NewNode(simplified()->DateNow(), effect, control);
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
Graph* JSCallReducer::graph() const { return jsgraph()->graph(); } Graph* JSCallReducer::graph() const { return jsgraph()->graph(); }
Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); } Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); }
......
...@@ -180,6 +180,9 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer { ...@@ -180,6 +180,9 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
InstanceType instance_type, InstanceType instance_type,
FieldAccess const& access); FieldAccess const& access);
Reduction ReduceDatePrototypeGetTime(Node* node);
Reduction ReduceDateNow(Node* node);
// Returns the updated {to} node, and updates control and effect along the // Returns the updated {to} node, and updates control and effect along the
// way. // way.
Node* DoFilterPostCallbackWork(ElementsKind kind, Node** control, Node* DoFilterPostCallbackWork(ElementsKind kind, Node** control,
......
...@@ -421,7 +421,8 @@ ...@@ -421,7 +421,8 @@
V(FindOrderedHashMapEntry) \ V(FindOrderedHashMapEntry) \
V(FindOrderedHashMapEntryForInt32Key) \ V(FindOrderedHashMapEntryForInt32Key) \
V(MaskIndexWithBound) \ V(MaskIndexWithBound) \
V(RuntimeAbort) V(RuntimeAbort) \
V(DateNow)
#define SIMPLIFIED_OP_LIST(V) \ #define SIMPLIFIED_OP_LIST(V) \
SIMPLIFIED_CHANGE_OP_LIST(V) \ SIMPLIFIED_CHANGE_OP_LIST(V) \
......
...@@ -3033,6 +3033,9 @@ class RepresentationSelector { ...@@ -3033,6 +3033,9 @@ class RepresentationSelector {
MachineRepresentation::kFloat64); MachineRepresentation::kFloat64);
if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
return; return;
case IrOpcode::kDateNow:
VisitInputs(node);
return SetOutput(node, MachineRepresentation::kTaggedPointer);
case IrOpcode::kFrameState: case IrOpcode::kFrameState:
return VisitFrameState(node); return VisitFrameState(node);
case IrOpcode::kStateValues: case IrOpcode::kStateValues:
......
...@@ -728,7 +728,8 @@ bool operator==(CheckMinusZeroParameters const& lhs, ...@@ -728,7 +728,8 @@ bool operator==(CheckMinusZeroParameters const& lhs,
#define EFFECT_DEPENDENT_OP_LIST(V) \ #define EFFECT_DEPENDENT_OP_LIST(V) \
V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \ V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \
V(StringSubstring, Operator::kNoProperties, 3, 1) V(StringSubstring, Operator::kNoProperties, 3, 1) \
V(DateNow, Operator::kNoProperties, 0, 1)
#define SPECULATIVE_NUMBER_BINOP_LIST(V) \ #define SPECULATIVE_NUMBER_BINOP_LIST(V) \
SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \ SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \
......
...@@ -729,6 +729,8 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final ...@@ -729,6 +729,8 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
// Abort (for terminating execution on internal error). // Abort (for terminating execution on internal error).
const Operator* RuntimeAbort(AbortReason reason); const Operator* RuntimeAbort(AbortReason reason);
const Operator* DateNow();
private: private:
Zone* zone() const { return zone_; } Zone* zone() const { return zone_; }
......
...@@ -1482,6 +1482,8 @@ Type* Typer::Visitor::TypeJSObjectIsArray(Node* node) { ...@@ -1482,6 +1482,8 @@ Type* Typer::Visitor::TypeJSObjectIsArray(Node* node) {
return Type::Boolean(); return Type::Boolean();
} }
Type* Typer::Visitor::TypeDateNow(Node* node) { return Type::Number(); }
Type* Typer::Visitor::JSCallTyper(Type* fun, Typer* t) { Type* Typer::Visitor::JSCallTyper(Type* fun, Typer* t) {
if (fun->IsHeapConstant() && fun->AsHeapConstant()->Value()->IsJSFunction()) { if (fun->IsHeapConstant() && fun->AsHeapConstant()->Value()->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction> function =
......
...@@ -1537,6 +1537,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { ...@@ -1537,6 +1537,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
case IrOpcode::kTypeGuard: case IrOpcode::kTypeGuard:
CheckTypeIs(node, TypeGuardTypeOf(node->op())); CheckTypeIs(node, TypeGuardTypeOf(node->op()));
break; break;
case IrOpcode::kDateNow:
CHECK_EQ(0, value_count);
CheckTypeIs(node, Type::Number());
break;
// Machine operators // Machine operators
// ----------------------- // -----------------------
......
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