diff options
Diffstat (limited to 'deps/v8/src/compiler/js-intrinsic-lowering.cc')
-rw-r--r-- | deps/v8/src/compiler/js-intrinsic-lowering.cc | 338 |
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(); } |