Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 4377b420705755d36223b319fc2119ab40bfcd42..c2b74fcbf4da398cad70f6aebb23e4cb1d03364f 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -4687,6 +4687,10 @@ HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
| void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
| + if (expr->is_this()) { |
| + current_info()->set_this_has_uses(true); |
| + } |
| + |
| ASSERT(!HasStackOverflow()); |
| ASSERT(current_block() != NULL); |
| ASSERT(current_block()->HasPredecessor()); |
| @@ -7210,15 +7214,13 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
| this, &target_info, inlining_kind); |
| HConstant* undefined = graph()->GetConstantUndefined(); |
| - bool undefined_receiver = HEnvironment::UseUndefinedReceiver( |
| - target, function, call_kind, inlining_kind); |
| + |
| HEnvironment* inner_env = |
| environment()->CopyForInlining(target, |
| arguments_count, |
| function, |
| undefined, |
| - function_state()->inlining_kind(), |
| - undefined_receiver); |
| + function_state()->inlining_kind()); |
| HConstant* context = Add<HConstant>(Handle<Context>(target->context())); |
| inner_env->BindContext(context); |
| @@ -7244,7 +7246,7 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, |
| Add<HEnterInlined>(target, arguments_count, function, |
| function_state()->inlining_kind(), |
| function->scope()->arguments(), |
| - arguments_object, undefined_receiver); |
| + arguments_object); |
| function_state()->set_entry(enter_inlined); |
| VisitDeclarations(target_info.scope()->declarations()); |
| @@ -7667,27 +7669,6 @@ bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { |
| } |
| -void HOptimizedGraphBuilder::InstallGlobalReceiverInExpressionStack( |
| - int receiver_index, |
| - Handle<JSFunction> function) { |
| - // TODO(dcarney): Fix deserializer to be able to hookup the global receiver |
| - // and object during deserialization and embed the global receiver here |
| - // directly. |
| - // Install global receiver on stack. |
| - HValue* function_constant = Add<HConstant>(function); |
| - HValue* context = Add<HLoadNamedField>( |
| - function_constant, |
| - HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset)); |
| - HValue* global_object = Add<HLoadNamedField>( |
| - context, |
| - HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| - HValue* global_receiver = Add<HLoadNamedField>( |
| - global_object, |
| - HObjectAccess::ForJSObjectOffset(GlobalObject::kGlobalReceiverOffset)); |
| - environment()->SetExpressionStackAt(receiver_index, global_receiver); |
| -} |
| - |
| - |
| void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| ASSERT(!HasStackOverflow()); |
| ASSERT(current_block() != NULL); |
| @@ -7802,17 +7783,33 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| // code generated by the full code generator expects it. |
| HGlobalObject* global_object = Add<HGlobalObject>(); |
| Push(global_object); |
| + |
| CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| CHECK_ALIVE(VisitForValue(expr->expression())); |
| HValue* function = Pop(); |
| Add<HCheckValue>(function, expr->target()); |
| - // Install global receiver on stack. |
| + // Patch the global object on the stack by the expected receiver. |
| + Handle<JSFunction> target = expr->target(); |
| + SharedFunctionInfo* shared = target->shared(); |
| + HValue* receiver; |
| const int receiver_index = argument_count - 1; |
| - ASSERT(environment()->ExpressionStackAt(receiver_index)-> |
| - IsGlobalObject()); |
| - InstallGlobalReceiverInExpressionStack(receiver_index, expr->target()); |
| + if (shared->is_classic_mode() && !shared->native()) { |
|
dcarney
2014/01/13 18:35:03
not really for this patch maybe, but:
is_classic_
|
| + HValue* context = Add<HLoadNamedField>( |
| + function, |
| + HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset)); |
| + HValue* global_object = Add<HLoadNamedField>( |
| + context, |
| + HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| + receiver = Add<HLoadNamedField>( |
| + global_object, |
| + HObjectAccess::ForJSObjectOffset( |
| + GlobalObject::kGlobalReceiverOffset)); |
| + } else { |
| + receiver = graph()->GetConstantUndefined(); |
| + } |
| + environment()->SetExpressionStackAt(receiver_index, receiver); |
| if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. |
| if (FLAG_trace_inlining) { |
| @@ -7831,6 +7828,8 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { |
| // We're about to install a contextual IC, which expects the global |
| // object as receiver rather than the global proxy. |
| + HGlobalObject* global_object = Add<HGlobalObject>(); |
| + const int receiver_index = argument_count - 1; |
| environment()->SetExpressionStackAt(receiver_index, global_object); |
| // When the target has a custom call IC generator, use the IC, |
| // because it is likely to generate better code. |
| @@ -7853,17 +7852,28 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| // evaluation of the arguments. |
| CHECK_ALIVE(VisitForValue(expr->expression())); |
| HValue* function = Top(); |
| - HGlobalObject* global = Add<HGlobalObject>(); |
| - HGlobalReceiver* receiver = Add<HGlobalReceiver>(global); |
| - Push(receiver); |
| - CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| + |
| Add<HCheckValue>(function, expr->target()); |
| - // Install global receiver on stack. |
| - const int receiver_index = argument_count - 1; |
| - ASSERT(environment()->ExpressionStackAt(receiver_index)-> |
| - IsGlobalReceiver()); |
| - InstallGlobalReceiverInExpressionStack(receiver_index, expr->target()); |
| + Handle<JSFunction> target = expr->target(); |
| + SharedFunctionInfo* shared = target->shared(); |
| + if (shared->is_classic_mode() && !shared->native()) { |
|
dcarney
2014/01/13 18:35:03
this block is identical to the above except for th
|
| + HValue* context = Add<HLoadNamedField>( |
| + function, |
| + HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset)); |
| + HValue* global_object = Add<HLoadNamedField>( |
| + context, |
| + HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| + HValue* global_receiver = Add<HLoadNamedField>( |
| + global_object, |
| + HObjectAccess::ForJSObjectOffset( |
| + GlobalObject::kGlobalReceiverOffset)); |
| + Push(global_receiver); |
| + } else { |
| + Push(graph()->GetConstantUndefined()); |
| + } |
| + |
| + CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
| if (FLAG_trace_inlining) { |
| @@ -7885,7 +7895,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| } else { |
| CHECK_ALIVE(VisitForValue(expr->expression())); |
| HValue* function = Top(); |
| - HValue* receiver = graph()->GetConstantHole(); |
| + HValue* receiver = graph()->GetConstantUndefined(); |
| Push(Add<HPushArgument>(receiver)); |
| CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| call = New<HCallFunction>( |
| @@ -10571,8 +10581,7 @@ HEnvironment* HEnvironment::CopyForInlining( |
| int arguments, |
| FunctionLiteral* function, |
| HConstant* undefined, |
| - InliningKind inlining_kind, |
| - bool undefined_receiver) const { |
| + InliningKind inlining_kind) const { |
| ASSERT(frame_type() == JS_FUNCTION); |
| // Outer environment is a copy of this one without the arguments. |
| @@ -10610,12 +10619,6 @@ HEnvironment* HEnvironment::CopyForInlining( |
| ExpressionStackAt(arguments - i) : undefined; |
| inner->SetValueAt(i, push); |
| } |
| - // If the function we are inlining is a strict mode function or a |
| - // builtin function, pass undefined as the receiver for function |
| - // calls (instead of the global receiver). |
| - if (undefined_receiver) { |
| - inner->SetValueAt(0, undefined); |
| - } |
| inner->SetValueAt(arity + 1, context()); |
| for (int i = arity + 2; i < inner->length(); ++i) { |
| inner->SetValueAt(i, undefined); |