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); |