summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/js-intrinsic-lowering.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/js-intrinsic-lowering.cc')
-rw-r--r--deps/v8/src/compiler/js-intrinsic-lowering.cc338
1 files changed, 178 insertions, 160 deletions
diff --git a/deps/v8/src/compiler/js-intrinsic-lowering.cc b/deps/v8/src/compiler/js-intrinsic-lowering.cc
index 379f8b7490..ca5cb932b4 100644
--- a/deps/v8/src/compiler/js-intrinsic-lowering.cc
+++ b/deps/v8/src/compiler/js-intrinsic-lowering.cc
@@ -37,16 +37,14 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
switch (f->function_id) {
case Runtime::kInlineConstructDouble:
return ReduceConstructDouble(node);
- case Runtime::kInlineDateField:
- return ReduceDateField(node);
+ case Runtime::kInlineCreateIterResultObject:
+ return ReduceCreateIterResultObject(node);
case Runtime::kInlineDeoptimizeNow:
return ReduceDeoptimizeNow(node);
case Runtime::kInlineDoubleHi:
return ReduceDoubleHi(node);
case Runtime::kInlineDoubleLo:
return ReduceDoubleLo(node);
- case Runtime::kInlineHeapObjectGetMap:
- return ReduceHeapObjectGetMap(node);
case Runtime::kInlineIncrementStatsCounter:
return ReduceIncrementStatsCounter(node);
case Runtime::kInlineIsArray:
@@ -56,31 +54,21 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
case Runtime::kInlineIsTypedArray:
return ReduceIsInstanceType(node, JS_TYPED_ARRAY_TYPE);
case Runtime::kInlineIsFunction:
- return ReduceIsInstanceType(node, JS_FUNCTION_TYPE);
+ return ReduceIsFunction(node);
case Runtime::kInlineIsRegExp:
return ReduceIsInstanceType(node, JS_REGEXP_TYPE);
+ case Runtime::kInlineIsJSReceiver:
+ return ReduceIsJSReceiver(node);
case Runtime::kInlineIsSmi:
return ReduceIsSmi(node);
case Runtime::kInlineJSValueGetValue:
return ReduceJSValueGetValue(node);
- case Runtime::kInlineMapGetInstanceType:
- return ReduceMapGetInstanceType(node);
case Runtime::kInlineMathClz32:
return ReduceMathClz32(node);
case Runtime::kInlineMathFloor:
return ReduceMathFloor(node);
case Runtime::kInlineMathSqrt:
return ReduceMathSqrt(node);
- case Runtime::kInlineOneByteSeqStringGetChar:
- return ReduceSeqStringGetChar(node, String::ONE_BYTE_ENCODING);
- case Runtime::kInlineOneByteSeqStringSetChar:
- return ReduceSeqStringSetChar(node, String::ONE_BYTE_ENCODING);
- case Runtime::kInlineStringGetLength:
- return ReduceStringGetLength(node);
- case Runtime::kInlineTwoByteSeqStringGetChar:
- return ReduceSeqStringGetChar(node, String::TWO_BYTE_ENCODING);
- case Runtime::kInlineTwoByteSeqStringSetChar:
- return ReduceSeqStringSetChar(node, String::TWO_BYTE_ENCODING);
case Runtime::kInlineValueOf:
return ReduceValueOf(node);
case Runtime::kInlineIsMinusZero:
@@ -89,10 +77,16 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceFixedArrayGet(node);
case Runtime::kInlineFixedArraySet:
return ReduceFixedArraySet(node);
- case Runtime::kInlineGetTypeFeedbackVector:
- return ReduceGetTypeFeedbackVector(node);
- case Runtime::kInlineGetCallerJSFunction:
- return ReduceGetCallerJSFunction(node);
+ case Runtime::kInlineRegExpConstructResult:
+ return ReduceRegExpConstructResult(node);
+ case Runtime::kInlineRegExpExec:
+ return ReduceRegExpExec(node);
+ case Runtime::kInlineRegExpFlags:
+ return ReduceRegExpFlags(node);
+ case Runtime::kInlineRegExpSource:
+ return ReduceRegExpSource(node);
+ case Runtime::kInlineSubString:
+ return ReduceSubString(node);
case Runtime::kInlineToInteger:
return ReduceToInteger(node);
case Runtime::kInlineToLength:
@@ -107,10 +101,12 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceToPrimitive(node);
case Runtime::kInlineToString:
return ReduceToString(node);
- case Runtime::kInlineThrowNotDateError:
- return ReduceThrowNotDateError(node);
case Runtime::kInlineCall:
return ReduceCall(node);
+ case Runtime::kInlineTailCall:
+ return ReduceTailCall(node);
+ case Runtime::kInlineGetSuperConstructor:
+ return ReduceGetSuperConstructor(node);
default:
break;
}
@@ -118,6 +114,16 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
}
+Reduction JSIntrinsicLowering::ReduceCreateIterResultObject(Node* node) {
+ Node* const value = NodeProperties::GetValueInput(node, 0);
+ Node* const done = NodeProperties::GetValueInput(node, 1);
+ Node* const context = NodeProperties::GetContextInput(node);
+ Node* const effect = NodeProperties::GetEffectInput(node);
+ return Change(node, javascript()->CreateIterResultObject(), value, done,
+ context, effect);
+}
+
+
Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) {
Node* high = NodeProperties::GetValueInput(node, 0);
Node* low = NodeProperties::GetValueInput(node, 1);
@@ -131,24 +137,6 @@ Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) {
}
-Reduction JSIntrinsicLowering::ReduceDateField(Node* node) {
- Node* const value = NodeProperties::GetValueInput(node, 0);
- Node* const index = NodeProperties::GetValueInput(node, 1);
- Node* const effect = NodeProperties::GetEffectInput(node);
- Node* const control = NodeProperties::GetControlInput(node);
- NumberMatcher mindex(index);
- if (mindex.Is(JSDate::kDateValue)) {
- return Change(
- node,
- simplified()->LoadField(AccessBuilder::ForJSDateField(
- static_cast<JSDate::FieldIndex>(static_cast<int>(mindex.Value())))),
- value, effect, control);
- }
- // TODO(turbofan): Optimize more patterns.
- return NoChange();
-}
-
-
Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
if (mode() != kDeoptimizationEnabled) return NoChange();
Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
@@ -157,7 +145,8 @@ Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
// TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
Node* deoptimize =
- graph()->NewNode(common()->Deoptimize(), frame_state, effect, control);
+ graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+ frame_state, effect, control);
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
node->TrimInputCount(0);
@@ -176,15 +165,6 @@ Reduction JSIntrinsicLowering::ReduceDoubleLo(Node* node) {
}
-Reduction JSIntrinsicLowering::ReduceHeapObjectGetMap(Node* node) {
- Node* value = NodeProperties::GetValueInput(node, 0);
- Node* effect = NodeProperties::GetEffectInput(node);
- Node* control = NodeProperties::GetControlInput(node);
- return Change(node, simplified()->LoadField(AccessBuilder::ForMap()), value,
- effect, control);
-}
-
-
Reduction JSIntrinsicLowering::ReduceIncrementStatsCounter(Node* node) {
if (!FLAG_native_code_counters) return ChangeToUndefined(node);
HeapObjectMatcher m(NodeProperties::GetValueInput(node, 0));
@@ -217,8 +197,6 @@ Reduction JSIntrinsicLowering::ReduceIsInstanceType(
// } else {
// return %_GetInstanceType(%_GetMap(value)) == instance_type;
// }
- MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged);
-
Node* value = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
@@ -246,31 +224,108 @@ Reduction JSIntrinsicLowering::ReduceIsInstanceType(
ReplaceWithValue(node, node, ephi);
// Turn the {node} into a Phi.
- return Change(node, common()->Phi(type, 2), vtrue, vfalse, merge);
+ return Change(node, common()->Phi(MachineRepresentation::kTagged, 2), vtrue,
+ vfalse, merge);
}
-Reduction JSIntrinsicLowering::ReduceIsSmi(Node* node) {
- return Change(node, simplified()->ObjectIsSmi());
+Reduction JSIntrinsicLowering::ReduceIsFunction(Node* node) {
+ Node* value = NodeProperties::GetValueInput(node, 0);
+ Type* value_type = NodeProperties::GetType(value);
+ Node* effect = NodeProperties::GetEffectInput(node);
+ Node* control = NodeProperties::GetControlInput(node);
+ if (value_type->Is(Type::Function())) {
+ value = jsgraph()->TrueConstant();
+ } else {
+ // if (%_IsSmi(value)) {
+ // return false;
+ // } else {
+ // return FIRST_FUNCTION_TYPE <= %_GetInstanceType(%_GetMap(value))
+ // }
+ STATIC_ASSERT(LAST_TYPE == LAST_FUNCTION_TYPE);
+
+ Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+ Node* branch = graph()->NewNode(common()->Branch(), check, control);
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* etrue = effect;
+ Node* vtrue = jsgraph()->FalseConstant();
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* efalse = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+ graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+ value, effect, if_false),
+ effect, if_false);
+ Node* vfalse =
+ graph()->NewNode(machine()->Uint32LessThanOrEqual(),
+ jsgraph()->Int32Constant(FIRST_FUNCTION_TYPE), efalse);
+
+ control = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
+ value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+ vtrue, vfalse, control);
+ }
+ ReplaceWithValue(node, node, effect, control);
+ return Replace(value);
}
-Reduction JSIntrinsicLowering::ReduceJSValueGetValue(Node* node) {
+Reduction JSIntrinsicLowering::ReduceIsJSReceiver(Node* node) {
Node* value = NodeProperties::GetValueInput(node, 0);
+ Type* value_type = NodeProperties::GetType(value);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
- return Change(node, simplified()->LoadField(AccessBuilder::ForValue()), value,
- effect, control);
+ if (value_type->Is(Type::Receiver())) {
+ value = jsgraph()->TrueConstant();
+ } else if (!value_type->Maybe(Type::Receiver())) {
+ value = jsgraph()->FalseConstant();
+ } else {
+ // if (%_IsSmi(value)) {
+ // return false;
+ // } else {
+ // return FIRST_JS_RECEIVER_TYPE <= %_GetInstanceType(%_GetMap(value))
+ // }
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
+
+ Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+ Node* branch = graph()->NewNode(common()->Branch(), check, control);
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* etrue = effect;
+ Node* vtrue = jsgraph()->FalseConstant();
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* efalse = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+ graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+ value, effect, if_false),
+ effect, if_false);
+ Node* vfalse = graph()->NewNode(
+ machine()->Uint32LessThanOrEqual(),
+ jsgraph()->Int32Constant(FIRST_JS_RECEIVER_TYPE), efalse);
+
+ control = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
+ value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+ vtrue, vfalse, control);
+ }
+ ReplaceWithValue(node, node, effect, control);
+ return Replace(value);
}
-Reduction JSIntrinsicLowering::ReduceMapGetInstanceType(Node* node) {
+Reduction JSIntrinsicLowering::ReduceIsSmi(Node* node) {
+ return Change(node, simplified()->ObjectIsSmi());
+}
+
+
+Reduction JSIntrinsicLowering::ReduceJSValueGetValue(Node* node) {
Node* value = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
- return Change(node,
- simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
- value, effect, control);
+ return Change(node, simplified()->LoadField(AccessBuilder::ForValue()), value,
+ effect, control);
}
@@ -290,53 +345,6 @@ Reduction JSIntrinsicLowering::ReduceMathSqrt(Node* node) {
}
-Reduction JSIntrinsicLowering::ReduceSeqStringGetChar(
- Node* node, String::Encoding encoding) {
- Node* effect = NodeProperties::GetEffectInput(node);
- Node* control = NodeProperties::GetControlInput(node);
- RelaxControls(node);
- node->ReplaceInput(2, effect);
- node->ReplaceInput(3, control);
- node->TrimInputCount(4);
- NodeProperties::ChangeOp(
- node,
- simplified()->LoadElement(AccessBuilder::ForSeqStringChar(encoding)));
- return Changed(node);
-}
-
-
-Reduction JSIntrinsicLowering::ReduceSeqStringSetChar(
- Node* node, String::Encoding encoding) {
- // Note: The intrinsic has a strange argument order, so we need to reshuffle.
- Node* index = NodeProperties::GetValueInput(node, 0);
- Node* chr = NodeProperties::GetValueInput(node, 1);
- Node* string = NodeProperties::GetValueInput(node, 2);
- Node* effect = NodeProperties::GetEffectInput(node);
- Node* control = NodeProperties::GetControlInput(node);
- ReplaceWithValue(node, string, node);
- NodeProperties::RemoveType(node);
- node->ReplaceInput(0, string);
- node->ReplaceInput(1, index);
- node->ReplaceInput(2, chr);
- node->ReplaceInput(3, effect);
- node->ReplaceInput(4, control);
- node->TrimInputCount(5);
- NodeProperties::ChangeOp(
- node,
- simplified()->StoreElement(AccessBuilder::ForSeqStringChar(encoding)));
- return Changed(node);
-}
-
-
-Reduction JSIntrinsicLowering::ReduceStringGetLength(Node* node) {
- Node* value = NodeProperties::GetValueInput(node, 0);
- Node* effect = NodeProperties::GetEffectInput(node);
- Node* control = NodeProperties::GetControlInput(node);
- return Change(node, simplified()->LoadField(AccessBuilder::ForStringLength()),
- value, effect, control);
-}
-
-
Reduction JSIntrinsicLowering::ReduceValueOf(Node* node) {
// if (%_IsSmi(value)) {
// return value;
@@ -347,7 +355,8 @@ Reduction JSIntrinsicLowering::ReduceValueOf(Node* node) {
// }
const Operator* const merge_op = common()->Merge(2);
const Operator* const ephi_op = common()->EffectPhi(2);
- const Operator* const phi_op = common()->Phi(kMachAnyTagged, 2);
+ const Operator* const phi_op =
+ common()->Phi(MachineRepresentation::kTagged, 2);
Node* value = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
@@ -460,57 +469,39 @@ Reduction JSIntrinsicLowering::ReduceFixedArraySet(Node* node) {
}
-Reduction JSIntrinsicLowering::ReduceGetTypeFeedbackVector(Node* node) {
- Node* func = node->InputAt(0);
- Node* effect = NodeProperties::GetEffectInput(node);
- Node* control = NodeProperties::GetControlInput(node);
- FieldAccess access = AccessBuilder::ForJSFunctionSharedFunctionInfo();
- Node* load =
- graph()->NewNode(simplified()->LoadField(access), func, effect, control);
- access = AccessBuilder::ForSharedFunctionInfoTypeFeedbackVector();
- return Change(node, simplified()->LoadField(access), load, load, control);
+Reduction JSIntrinsicLowering::ReduceRegExpConstructResult(Node* node) {
+ // TODO(bmeurer): Introduce JSCreateRegExpResult?
+ return Change(node, CodeFactory::RegExpConstructResult(isolate()), 0);
}
-Reduction JSIntrinsicLowering::ReduceGetCallerJSFunction(Node* node) {
- Node* effect = NodeProperties::GetEffectInput(node);
- Node* control = NodeProperties::GetControlInput(node);
+Reduction JSIntrinsicLowering::ReduceRegExpExec(Node* node) {
+ return Change(node, CodeFactory::RegExpExec(isolate()), 4);
+}
- Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
- Node* outer_frame = frame_state->InputAt(kFrameStateOuterStateInput);
- if (outer_frame->opcode() == IrOpcode::kFrameState) {
- // Use the runtime implementation to throw the appropriate error if the
- // containing function is inlined.
- return NoChange();
- }
- // TODO(danno): This implementation forces intrinsic lowering to happen after
- // inlining, which is fine for now, but eventually the frame-querying logic
- // probably should go later, e.g. in instruction selection, so that there is
- // no phase-ordering dependency.
- FieldAccess access = AccessBuilder::ForFrameCallerFramePtr();
- Node* fp = graph()->NewNode(machine()->LoadFramePointer());
- Node* next_fp =
- graph()->NewNode(simplified()->LoadField(access), fp, effect, control);
- return Change(node, simplified()->LoadField(AccessBuilder::ForFrameMarker()),
- next_fp, effect, control);
+Reduction JSIntrinsicLowering::ReduceRegExpFlags(Node* node) {
+ Node* const receiver = NodeProperties::GetValueInput(node, 0);
+ Node* const effect = NodeProperties::GetEffectInput(node);
+ Node* const control = NodeProperties::GetControlInput(node);
+ Operator const* const op =
+ simplified()->LoadField(AccessBuilder::ForJSRegExpFlags());
+ return Change(node, op, receiver, effect, control);
}
-Reduction JSIntrinsicLowering::ReduceThrowNotDateError(Node* node) {
- if (mode() != kDeoptimizationEnabled) return NoChange();
- Node* const frame_state = NodeProperties::GetFrameStateInput(node, 1);
+Reduction JSIntrinsicLowering::ReduceRegExpSource(Node* node) {
+ Node* const receiver = NodeProperties::GetValueInput(node, 0);
Node* const effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node);
+ Operator const* const op =
+ simplified()->LoadField(AccessBuilder::ForJSRegExpSource());
+ return Change(node, op, receiver, effect, control);
+}
- // TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
- Node* deoptimize =
- graph()->NewNode(common()->Deoptimize(), frame_state, effect, control);
- NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
- node->TrimInputCount(0);
- NodeProperties::ChangeOp(node, common()->Dead());
- return Changed(node);
+Reduction JSIntrinsicLowering::ReduceSubString(Node* node) {
+ return Change(node, CodeFactory::SubString(isolate()), 3);
}
@@ -548,7 +539,7 @@ Reduction JSIntrinsicLowering::ReduceToLength(Node* node) {
} else {
if (value_type->Min() <= 0.0) {
value = graph()->NewNode(
- common()->Select(kMachAnyTagged),
+ common()->Select(MachineRepresentation::kTagged),
graph()->NewNode(simplified()->NumberLessThanOrEqual(), value,
jsgraph()->ZeroConstant()),
jsgraph()->ZeroConstant(), value);
@@ -557,7 +548,7 @@ Reduction JSIntrinsicLowering::ReduceToLength(Node* node) {
}
if (value_type->Max() > kMaxSafeInteger) {
value = graph()->NewNode(
- common()->Select(kMachAnyTagged),
+ common()->Select(MachineRepresentation::kTagged),
graph()->NewNode(simplified()->NumberLessThanOrEqual(),
jsgraph()->Constant(kMaxSafeInteger), value),
jsgraph()->Constant(kMaxSafeInteger), value);
@@ -569,14 +560,7 @@ Reduction JSIntrinsicLowering::ReduceToLength(Node* node) {
ReplaceWithValue(node, value);
return Replace(value);
}
- Callable callable = CodeFactory::ToLength(isolate());
- CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
- isolate(), graph()->zone(), callable.descriptor(), 0,
- CallDescriptor::kNeedsFrameState, node->op()->properties());
- node->InsertInput(graph()->zone(), 0,
- jsgraph()->HeapConstant(callable.code()));
- NodeProperties::ChangeOp(node, common()->Call(desc));
- return Changed(node);
+ return Change(node, CodeFactory::ToLength(isolate()), 0);
}
@@ -608,11 +592,33 @@ Reduction JSIntrinsicLowering::ReduceCall(Node* node) {
NodeProperties::ChangeOp(
node, javascript()->CallFunction(arity, STRICT, VectorSlotPair(),
ConvertReceiverMode::kAny,
+ TailCallMode::kDisallow));
+ return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceTailCall(Node* node) {
+ size_t const arity = CallRuntimeParametersOf(node->op()).arity();
+ NodeProperties::ChangeOp(
+ node, javascript()->CallFunction(arity, STRICT, VectorSlotPair(),
+ ConvertReceiverMode::kAny,
TailCallMode::kAllow));
return Changed(node);
}
+Reduction JSIntrinsicLowering::ReduceGetSuperConstructor(Node* node) {
+ Node* active_function = NodeProperties::GetValueInput(node, 0);
+ Node* effect = NodeProperties::GetEffectInput(node);
+ Node* control = NodeProperties::GetControlInput(node);
+ Node* active_function_map = effect =
+ graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+ active_function, effect, control);
+ return Change(node, simplified()->LoadField(AccessBuilder::ForMapPrototype()),
+ active_function_map, effect, control);
+}
+
+
Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
Node* b) {
RelaxControls(node);
@@ -655,6 +661,18 @@ Reduction JSIntrinsicLowering::ChangeToUndefined(Node* node, Node* effect) {
}
+Reduction JSIntrinsicLowering::Change(Node* node, Callable const& callable,
+ int stack_parameter_count) {
+ CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
+ isolate(), graph()->zone(), callable.descriptor(), stack_parameter_count,
+ CallDescriptor::kNeedsFrameState, node->op()->properties());
+ node->InsertInput(graph()->zone(), 0,
+ jsgraph()->HeapConstant(callable.code()));
+ NodeProperties::ChangeOp(node, common()->Call(desc));
+ return Changed(node);
+}
+
+
Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); }