[turbofan] Use proper eager deopts for %_ThrowNotDateError().

R=jarin@chromium.org

Review URL: https://codereview.chromium.org/1210863002

Cr-Commit-Position: refs/heads/master@{#29309}
This commit is contained in:
bmeurer 2015-06-25 22:56:00 -07:00 committed by Commit bot
parent cf21d22fd8
commit 9ad117657b
16 changed files with 52 additions and 11 deletions

View File

@ -4748,6 +4748,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
EmitCallJSRuntimeFunction(expr);
// Restore context register.
@ -4773,6 +4774,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
// Call the C runtime function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(expr->function(), arg_count);
context()->Plug(r0);
}

View File

@ -4441,6 +4441,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
EmitCallJSRuntimeFunction(expr);
// Restore context register.
@ -4466,6 +4467,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
// Call the C runtime function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(expr->function(), arg_count);
context()->Plug(x0);
}

View File

@ -2029,7 +2029,8 @@ class CallRuntime final : public Expression {
return callruntime_feedback_slot_;
}
static int num_ids() { return parent_num_ids(); }
static int num_ids() { return parent_num_ids() + 1; }
BailoutId CallId() { return BailoutId(local_id(0)); }
protected:
CallRuntime(Zone* zone, const AstRawString* name,
@ -2043,6 +2044,8 @@ class CallRuntime final : public Expression {
static int parent_num_ids() { return Expression::num_ids(); }
private:
int local_id(int n) const { return base_id() + parent_num_ids() + n; }
const AstRawString* raw_name_;
const Runtime::Function* function_;
ZoneList<Expression*>* arguments_;

View File

@ -2552,8 +2552,9 @@ void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
if (functionId == Runtime::kInlineGeneratorNext) SetStackOverflow();
if (functionId == Runtime::kInlineGeneratorThrow) SetStackOverflow();
const Operator* call = javascript()->CallRuntime(functionId, args->length());
FrameStateBeforeAndAfter states(this, expr->CallId());
Node* value = ProcessArguments(call, args->length());
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
}

View File

@ -92,6 +92,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceGetTypeFeedbackVector(node);
case Runtime::kInlineGetCallerJSFunction:
return ReduceGetCallerJSFunction(node);
case Runtime::kInlineThrowNotDateError:
return ReduceThrowNotDateError(node);
default:
break;
}
@ -494,6 +496,23 @@ Reduction JSIntrinsicLowering::ReduceGetCallerJSFunction(Node* node) {
}
Reduction JSIntrinsicLowering::ReduceThrowNotDateError(Node* node) {
if (mode() != kDeoptimizationEnabled) return NoChange();
Node* const frame_state = NodeProperties::GetFrameStateInput(node, 1);
Node* const effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node);
// TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
Node* deoptimize =
graph()->NewNode(common()->Deoptimize(), frame_state, effect, control);
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
node->set_op(common()->Dead());
node->TrimInputCount(0);
return Changed(node);
}
Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
Node* b) {
node->set_op(op);

View File

@ -55,6 +55,7 @@ class JSIntrinsicLowering final : public AdvancedReducer {
Reduction ReduceFixedArraySet(Node* node);
Reduction ReduceGetTypeFeedbackVector(Node* node);
Reduction ReduceGetCallerJSFunction(Node* node);
Reduction ReduceThrowNotDateError(Node* node);
Reduction Change(Node* node, const Operator* op);
Reduction Change(Node* node, const Operator* op, Node* a, Node* b);

View File

@ -115,7 +115,7 @@ class LinkageHelper {
locations.AddParam(regloc(LinkageTraits::ContextReg()));
types.AddParam(kMachAnyTagged);
CallDescriptor::Flags flags = Linkage::NeedsFrameState(function_id)
CallDescriptor::Flags flags = Linkage::FrameStateInputCount(function_id) > 0
? CallDescriptor::kNeedsFrameState
: CallDescriptor::kNoFlags;

View File

@ -105,7 +105,7 @@ FrameOffset Linkage::GetFrameOffset(int spill_slot, Frame* frame,
// static
bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
int Linkage::FrameStateInputCount(Runtime::FunctionId 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 blacklisted here and can be called without a FrameState.
@ -129,15 +129,16 @@ bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
case Runtime::kToFastProperties: // TODO(jarin): Is it safe?
case Runtime::kTraceEnter:
case Runtime::kTraceExit:
return false;
return 0;
case Runtime::kInlineArguments:
case Runtime::kInlineCallFunction:
case Runtime::kInlineDeoptimizeNow:
case Runtime::kInlineGetCallerJSFunction:
case Runtime::kInlineGetPrototype:
case Runtime::kInlineRegExpExec:
return 1;
case Runtime::kInlineDeoptimizeNow:
case Runtime::kInlineThrowNotDateError:
return true;
return 2;
default:
break;
}
@ -145,9 +146,9 @@ bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
// Most inlined runtime functions (except the ones listed above) can be called
// without a FrameState or will be lowered by JSIntrinsicLowering internally.
const Runtime::Function* const f = Runtime::FunctionForId(function);
if (f->intrinsic_type == Runtime::IntrinsicType::INLINE) return false;
if (f->intrinsic_type == Runtime::IntrinsicType::INLINE) return 0;
return true;
return 1;
}

View File

@ -251,7 +251,7 @@ class Linkage : public ZoneObject {
// the frame offset, e.g. to index into part of a double slot.
FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0) const;
static bool NeedsFrameState(Runtime::FunctionId function);
static int FrameStateInputCount(Runtime::FunctionId function);
// Get the location where an incoming OSR value is stored.
LinkageLocation GetOsrValueLocation(int index) const;

View File

@ -26,7 +26,7 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
return 1;
case IrOpcode::kJSCallRuntime: {
const CallRuntimeParameters& p = CallRuntimeParametersOf(op);
return Linkage::NeedsFrameState(p.id());
return Linkage::FrameStateInputCount(p.id());
}
// Strict equality cannot lazily deoptimize.

View File

@ -4682,6 +4682,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
EmitCallJSRuntimeFunction(expr);
// Restore context register.
@ -4706,6 +4707,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
// Call the C runtime function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(expr->function(), arg_count);
context()->Plug(eax);
}

View File

@ -4765,6 +4765,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
EmitCallJSRuntimeFunction(expr);
// Restore context register.
@ -4790,6 +4791,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
// Call the C runtime function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(expr->function(), arg_count);
context()->Plug(v0);
}

View File

@ -4768,6 +4768,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
EmitCallJSRuntimeFunction(expr);
// Restore context register.
@ -4792,6 +4793,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
// Call the C runtime function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(expr->function(), arg_count);
context()->Plug(v0);
}

View File

@ -4777,6 +4777,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
EmitCallJSRuntimeFunction(expr);
// Restore context register.
@ -4802,6 +4803,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
// Call the C runtime function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(expr->function(), arg_count);
context()->Plug(r3);
}

View File

@ -4706,6 +4706,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
EmitCallJSRuntimeFunction(expr);
// Restore context register.
@ -4730,6 +4731,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
// Call the C runtime.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(function, arg_count);
context()->Plug(rax);
}

View File

@ -4664,6 +4664,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
VisitForStackValue(args->at(i));
}
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
EmitCallJSRuntimeFunction(expr);
// Restore context register.
@ -4688,6 +4689,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
// Call the C runtime function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(expr->function(), arg_count);
context()->Plug(eax);
}