Revision: 8445
Author: [email protected]
Date: Tue Jun 28 05:51:21 2011
Log: Better placement of argument pushing for a few hydrogen call
instructions.
Where it's simple to do so (keyed calls, calls to unknown global variables,
calls to local variables and non-property/non-variable expressions), end the
live range of argument subexpressions immediately after the last use of the
expression rather than at the call.
[email protected]
BUG=
TEST=
Review URL: http://codereview.chromium.org/7274020
http://code.google.com/p/v8/source/detail?r=8445
Modified:
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Tue Jun 28 01:54:09 2011
+++ /branches/bleeding_edge/src/hydrogen.cc Tue Jun 28 05:51:21 2011
@@ -2179,9 +2179,12 @@
}
-void HGraphBuilder::VisitArgument(Expression* expr) {
- CHECK_ALIVE(VisitForValue(expr));
- Push(AddInstruction(new(zone()) HPushArgument(Pop())));
+HValue* HGraphBuilder::VisitArgument(Expression* expr) {
+ VisitForValue(expr);
+ if (HasStackOverflow() || current_block() == NULL) return NULL;
+ HValue* value = Pop();
+ Push(AddInstruction(new(zone()) HPushArgument(value)));
+ return value;
}
@@ -4691,7 +4694,7 @@
if (prop != NULL) {
if (!prop->key()->IsPropertyName()) {
// Keyed function call.
- CHECK_ALIVE(VisitForValue(prop->obj()));
+ CHECK_ALIVE(VisitArgument(prop->obj()));
CHECK_ALIVE(VisitForValue(prop->key()));
// Push receiver and key like the non-optimized code generator
expects it.
@@ -4700,13 +4703,12 @@
Push(key);
Push(receiver);
- CHECK_ALIVE(VisitExpressions(expr->arguments()));
+ CHECK_ALIVE(VisitArgumentList(expr->arguments()));
HValue* context = environment()->LookupContext();
- call = PreProcessCall(
- new(zone()) HCallKeyed(context, key, argument_count));
+ call = new(zone()) HCallKeyed(context, key, argument_count);
call->set_position(expr->position());
- Drop(1); // Key.
+ Drop(argument_count + 1); // 1 is the key.
ast_context()->ReturnInstruction(call, expr->id());
return;
}
@@ -4766,11 +4768,6 @@
Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
bool global_call = (var != NULL) && var->is_global()
&& !var->is_this();
- if (!global_call) {
- ++argument_count;
- CHECK_ALIVE(VisitForValue(expr->expression()));
- }
-
if (global_call) {
bool known_global_function = false;
// If there is a global property cell for the name at compile time
and
@@ -4810,22 +4807,29 @@
argument_count));
} else {
HValue* context = environment()->LookupContext();
- PushAndAdd(new(zone()) HGlobalObject(context));
- CHECK_ALIVE(VisitExpressions(expr->arguments()));
-
- call = PreProcessCall(new(zone()) HCallGlobal(context,
- var->name(),
- argument_count));
+ HGlobalObject* receiver = new(zone()) HGlobalObject(context);
+ AddInstruction(receiver);
+ PushAndAdd(new(zone()) HPushArgument(receiver));
+ CHECK_ALIVE(VisitArgumentList(expr->arguments()));
+
+ call = new(zone()) HCallGlobal(context, var->name(),
argument_count);
+ Drop(argument_count);
}
} else {
+ CHECK_ALIVE(VisitArgument(expr->expression()));
HValue* context = environment()->LookupContext();
HGlobalObject* global_object = new(zone()) HGlobalObject(context);
+ HGlobalReceiver* receiver = new(zone())
HGlobalReceiver(global_object);
AddInstruction(global_object);
- PushAndAdd(new(zone()) HGlobalReceiver(global_object));
- CHECK_ALIVE(VisitExpressions(expr->arguments()));
-
- call = PreProcessCall(new(zone()) HCallFunction(context,
argument_count));
+ AddInstruction(receiver);
+ PushAndAdd(new(zone()) HPushArgument(receiver));
+ CHECK_ALIVE(VisitArgumentList(expr->arguments()));
+
+ // The function to call is treated as an argument to the call
function
+ // stub.
+ call = new(zone()) HCallFunction(context, argument_count + 1);
+ Drop(argument_count + 1);
}
}
@@ -4840,18 +4844,18 @@
ASSERT(current_block()->HasPredecessor());
// The constructor function is also used as the receiver argument to the
// JS construct call builtin.
- CHECK_ALIVE(VisitForValue(expr->expression()));
- CHECK_ALIVE(VisitExpressions(expr->arguments()));
+ HValue* constructor = NULL;
+ CHECK_ALIVE(constructor = VisitArgument(expr->expression()));
+ CHECK_ALIVE(VisitArgumentList(expr->arguments()));
HValue* context = environment()->LookupContext();
// The constructor is both an operand to the instruction and an argument
// to the construct call.
int arg_count = expr->arguments()->length() + 1; // Plus constructor.
- HValue* constructor = environment()->ExpressionStackAt(arg_count - 1);
HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count);
call->set_position(expr->position());
- PreProcessCall(call);
+ Drop(arg_count);
ast_context()->ReturnInstruction(call, expr->id());
}
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Tue Jun 28 01:54:09 2011
+++ /branches/bleeding_edge/src/hydrogen.h Tue Jun 28 05:51:21 2011
@@ -816,8 +816,9 @@
HBasicBlock* false_block);
// Visit an argument subexpression and emit a push to the outgoing
- // arguments.
- void VisitArgument(Expression* expr);
+ // arguments. Returns the hydrogen value that was pushed.
+ HValue* VisitArgument(Expression* expr);
+
void VisitArgumentList(ZoneList<Expression*>* arguments);
// Visit a list of expressions from left to right, each in a value
context.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev