Commit d0edd08e authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[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}
parent 2baea747
...@@ -600,20 +600,15 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { ...@@ -600,20 +600,15 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
Node* context = jsgraph()->Constant(handle(function->context())); Node* context = jsgraph()->Constant(handle(function->context()));
// Insert a JSConvertReceiver node for sloppy callees. Note that the 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 // passed into this node has to be the callees context (loaded above).
// 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.
if (node->opcode() == IrOpcode::kJSCall && if (node->opcode() == IrOpcode::kJSCall &&
is_sloppy(shared_info->language_mode()) && !shared_info->native()) { is_sloppy(shared_info->language_mode()) && !shared_info->native()) {
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
if (NeedsConvertReceiver(call.receiver(), effect)) { if (NeedsConvertReceiver(call.receiver(), effect)) {
const CallParameters& p = CallParametersOf(node->op()); const CallParameters& p = CallParametersOf(node->op());
Node* frame_state_before = NodeProperties::FindFrameStateBefore(node); Node* convert = effect =
Node* convert = effect = graph()->NewNode( graph()->NewNode(javascript()->ConvertReceiver(p.convert_mode()),
javascript()->ConvertReceiver(p.convert_mode()), call.receiver(), call.receiver(), context, effect, start);
context, frame_state_before, effect, start);
NodeProperties::ReplaceValueInput(node, convert, 1); NodeProperties::ReplaceValueInput(node, convert, 1);
NodeProperties::ReplaceEffectInput(node, effect); NodeProperties::ReplaceEffectInput(node, effect);
} }
......
...@@ -1715,7 +1715,6 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { ...@@ -1715,7 +1715,6 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
Type* receiver_type = NodeProperties::GetType(receiver); Type* receiver_type = NodeProperties::GetType(receiver);
Node* context = NodeProperties::GetContextInput(node); Node* context = NodeProperties::GetContextInput(node);
Type* context_type = NodeProperties::GetType(context); Type* context_type = NodeProperties::GetType(context);
Node* frame_state = NodeProperties::GetFrameStateInput(node);
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
...@@ -1762,14 +1761,15 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { ...@@ -1762,14 +1761,15 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
Node* efalse = effect; Node* efalse = effect;
Node* rfalse; 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()); Callable callable = CodeFactory::ToObject(isolate());
CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), callable.descriptor(), 0, isolate(), graph()->zone(), callable.descriptor(), 0,
CallDescriptor::kNeedsFrameState, node->op()->properties()); CallDescriptor::kNoFlags, node->op()->properties());
rfalse = efalse = graph()->NewNode( rfalse = efalse = graph()->NewNode(
common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 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); control = graph()->NewNode(common()->Merge(2), if_true, if_false);
...@@ -1819,14 +1819,15 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { ...@@ -1819,14 +1819,15 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
Node* econvert = effect; Node* econvert = effect;
Node* rconvert; 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()); Callable callable = CodeFactory::ToObject(isolate());
CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), callable.descriptor(), 0, isolate(), graph()->zone(), callable.descriptor(), 0,
CallDescriptor::kNeedsFrameState, node->op()->properties()); CallDescriptor::kNoFlags, node->op()->properties());
rconvert = econvert = graph()->NewNode( rconvert = econvert = graph()->NewNode(
common()->Call(desc), jsgraph()->HeapConstant(callable.code()), common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
receiver, context, frame_state, econvert); receiver, context, econvert);
} }
// Replace {receiver} with global proxy of {context}. // Replace {receiver} with global proxy of {context}.
...@@ -2063,7 +2064,6 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) { ...@@ -2063,7 +2064,6 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
Type* receiver_type = NodeProperties::GetType(receiver); Type* receiver_type = NodeProperties::GetType(receiver);
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
Node* frame_state = NodeProperties::FindFrameStateBefore(node);
// Try to infer receiver {convert_mode} from {receiver} type. // Try to infer receiver {convert_mode} from {receiver} type.
if (receiver_type->Is(Type::NullOrUndefined())) { if (receiver_type->Is(Type::NullOrUndefined())) {
...@@ -2096,7 +2096,7 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) { ...@@ -2096,7 +2096,7 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
!receiver_type->Is(Type::Receiver())) { !receiver_type->Is(Type::Receiver())) {
receiver = effect = receiver = effect =
graph()->NewNode(javascript()->ConvertReceiver(convert_mode), graph()->NewNode(javascript()->ConvertReceiver(convert_mode),
receiver, context, frame_state, effect, control); receiver, context, effect, control);
NodeProperties::ReplaceValueInput(node, receiver, 1); NodeProperties::ReplaceValueInput(node, receiver, 1);
} }
......
...@@ -142,11 +142,11 @@ CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) { ...@@ -142,11 +142,11 @@ CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
bool Linkage::NeedsFrameStateInput(Runtime::FunctionId function) { bool Linkage::NeedsFrameStateInput(Runtime::FunctionId function) {
switch (function) { switch (function) {
// Most runtime functions need a FrameState. A few chosen ones that we know // 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 // not to call into arbitrary JavaScript, not to throw, and not to lazily
// deoptimize // deoptimize are whitelisted here and can be called without a FrameState.
// are whitelisted here and can be called without a FrameState.
case Runtime::kAbort: case Runtime::kAbort:
case Runtime::kAllocateInTargetSpace: case Runtime::kAllocateInTargetSpace:
case Runtime::kConvertReceiver:
case Runtime::kCreateIterResultObject: case Runtime::kCreateIterResultObject:
case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe? case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe?
case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe? case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe?
......
...@@ -100,7 +100,6 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) { ...@@ -100,7 +100,6 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSCallWithSpread: case IrOpcode::kJSCallWithSpread:
// Misc operations // Misc operations
case IrOpcode::kJSConvertReceiver:
case IrOpcode::kJSForInNext: case IrOpcode::kJSForInNext:
case IrOpcode::kJSForInPrepare: case IrOpcode::kJSForInPrepare:
case IrOpcode::kJSStackCheck: case IrOpcode::kJSStackCheck:
......
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