| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 4377b420705755d36223b319fc2119ab40bfcd42..db53cef43297c97872f7b06af93718193d52649a 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,24 +7669,22 @@ 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);
|
| +HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
|
| + Handle<JSFunction> target) {
|
| + SharedFunctionInfo* shared = target->shared();
|
| + if (shared->is_classic_mode() && !shared->native()) {
|
| + HValue* context = Add<HLoadNamedField>(
|
| + function,
|
| + HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset));
|
| + HValue* global_object = Add<HLoadNamedField>(
|
| + context,
|
| + HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
|
| + return Add<HLoadNamedField>(
|
| + global_object,
|
| + HObjectAccess::ForJSObjectOffset(
|
| + GlobalObject::kGlobalReceiverOffset));
|
| + }
|
| + return graph()->GetConstantUndefined();
|
| }
|
|
|
|
|
| @@ -7802,17 +7802,17 @@ 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.
|
| + HValue* receiver = ImplicitReceiverFor(function, expr->target());
|
| const int receiver_index = argument_count - 1;
|
| - ASSERT(environment()->ExpressionStackAt(receiver_index)->
|
| - IsGlobalObject());
|
| - InstallGlobalReceiverInExpressionStack(receiver_index, expr->target());
|
| + environment()->SetExpressionStackAt(receiver_index, receiver);
|
|
|
| if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop.
|
| if (FLAG_trace_inlining) {
|
| @@ -7831,6 +7831,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 +7855,13 @@ 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());
|
| + HValue* receiver = ImplicitReceiverFor(function, expr->target());
|
| + Push(receiver);
|
| +
|
| + CHECK_ALIVE(VisitExpressions(expr->arguments()));
|
|
|
| if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
|
| if (FLAG_trace_inlining) {
|
| @@ -7885,7 +7883,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 +10569,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 +10607,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);
|
|
|