[turbofan] Remove frame-state from {JSConvertReceiver}.
The operator in question does not call arbitrary JavaSciprt, nor throw, nor trigger a lazy deoptimization. Nodes hence do not need a frame-state representing the "after" state of the operation. R=bmeurer@chromium.org Review-Url: https://codereview.chromium.org/2672763002 Cr-Commit-Position: refs/heads/master@{#42891}
This commit is contained in:
parent
2baea747de
commit
d0edd08eb5
@ -600,20 +600,15 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
|
||||
Node* context = jsgraph()->Constant(handle(function->context()));
|
||||
|
||||
// Insert a JSConvertReceiver node for sloppy callees. Note that the context
|
||||
// passed into this node has to be the callees context (loaded above). Note
|
||||
// that the frame state passed to the JSConvertReceiver must be the frame
|
||||
// state _before_ the call; it is not necessary to fiddle with the receiver
|
||||
// in that frame state tho, as the conversion of the receiver can be repeated
|
||||
// any number of times, it's not observable.
|
||||
// passed into this node has to be the callees context (loaded above).
|
||||
if (node->opcode() == IrOpcode::kJSCall &&
|
||||
is_sloppy(shared_info->language_mode()) && !shared_info->native()) {
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
if (NeedsConvertReceiver(call.receiver(), effect)) {
|
||||
const CallParameters& p = CallParametersOf(node->op());
|
||||
Node* frame_state_before = NodeProperties::FindFrameStateBefore(node);
|
||||
Node* convert = effect = graph()->NewNode(
|
||||
javascript()->ConvertReceiver(p.convert_mode()), call.receiver(),
|
||||
context, frame_state_before, effect, start);
|
||||
Node* convert = effect =
|
||||
graph()->NewNode(javascript()->ConvertReceiver(p.convert_mode()),
|
||||
call.receiver(), context, effect, start);
|
||||
NodeProperties::ReplaceValueInput(node, convert, 1);
|
||||
NodeProperties::ReplaceEffectInput(node, effect);
|
||||
}
|
||||
|
@ -1715,7 +1715,6 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
|
||||
Type* receiver_type = NodeProperties::GetType(receiver);
|
||||
Node* context = NodeProperties::GetContextInput(node);
|
||||
Type* context_type = NodeProperties::GetType(context);
|
||||
Node* frame_state = NodeProperties::GetFrameStateInput(node);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
|
||||
@ -1762,14 +1761,15 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
|
||||
Node* efalse = effect;
|
||||
Node* rfalse;
|
||||
{
|
||||
// Convert {receiver} using the ToObjectStub.
|
||||
// Convert {receiver} using the ToObjectStub. The call does not require a
|
||||
// frame-state in this case, because neither null nor undefined is passed.
|
||||
Callable callable = CodeFactory::ToObject(isolate());
|
||||
CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
|
||||
isolate(), graph()->zone(), callable.descriptor(), 0,
|
||||
CallDescriptor::kNeedsFrameState, node->op()->properties());
|
||||
CallDescriptor::kNoFlags, node->op()->properties());
|
||||
rfalse = efalse = graph()->NewNode(
|
||||
common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
|
||||
receiver, context, frame_state, efalse);
|
||||
receiver, context, efalse);
|
||||
}
|
||||
|
||||
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
|
||||
@ -1819,14 +1819,15 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
|
||||
Node* econvert = effect;
|
||||
Node* rconvert;
|
||||
{
|
||||
// Convert {receiver} using the ToObjectStub.
|
||||
// Convert {receiver} using the ToObjectStub. The call does not require a
|
||||
// frame-state in this case, because neither null nor undefined is passed.
|
||||
Callable callable = CodeFactory::ToObject(isolate());
|
||||
CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
|
||||
isolate(), graph()->zone(), callable.descriptor(), 0,
|
||||
CallDescriptor::kNeedsFrameState, node->op()->properties());
|
||||
CallDescriptor::kNoFlags, node->op()->properties());
|
||||
rconvert = econvert = graph()->NewNode(
|
||||
common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
|
||||
receiver, context, frame_state, econvert);
|
||||
receiver, context, econvert);
|
||||
}
|
||||
|
||||
// Replace {receiver} with global proxy of {context}.
|
||||
@ -2063,7 +2064,6 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
|
||||
Type* receiver_type = NodeProperties::GetType(receiver);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
Node* frame_state = NodeProperties::FindFrameStateBefore(node);
|
||||
|
||||
// Try to infer receiver {convert_mode} from {receiver} type.
|
||||
if (receiver_type->Is(Type::NullOrUndefined())) {
|
||||
@ -2096,7 +2096,7 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
|
||||
!receiver_type->Is(Type::Receiver())) {
|
||||
receiver = effect =
|
||||
graph()->NewNode(javascript()->ConvertReceiver(convert_mode),
|
||||
receiver, context, frame_state, effect, control);
|
||||
receiver, context, effect, control);
|
||||
NodeProperties::ReplaceValueInput(node, receiver, 1);
|
||||
}
|
||||
|
||||
|
@ -142,11 +142,11 @@ CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
|
||||
bool Linkage::NeedsFrameStateInput(Runtime::FunctionId function) {
|
||||
switch (function) {
|
||||
// Most runtime functions need a FrameState. A few chosen ones that we know
|
||||
// not to call into arbitrary JavaScript, not to throw, and not to
|
||||
// deoptimize
|
||||
// are whitelisted here and can be called without a FrameState.
|
||||
// not to call into arbitrary JavaScript, not to throw, and not to lazily
|
||||
// deoptimize are whitelisted here and can be called without a FrameState.
|
||||
case Runtime::kAbort:
|
||||
case Runtime::kAllocateInTargetSpace:
|
||||
case Runtime::kConvertReceiver:
|
||||
case Runtime::kCreateIterResultObject:
|
||||
case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe?
|
||||
case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe?
|
||||
|
@ -100,7 +100,6 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
|
||||
case IrOpcode::kJSCallWithSpread:
|
||||
|
||||
// Misc operations
|
||||
case IrOpcode::kJSConvertReceiver:
|
||||
case IrOpcode::kJSForInNext:
|
||||
case IrOpcode::kJSForInPrepare:
|
||||
case IrOpcode::kJSStackCheck:
|
||||
|
Loading…
Reference in New Issue
Block a user