| Index: src/hydrogen.cc
|
| ===================================================================
|
| --- src/hydrogen.cc (revision 10631)
|
| +++ src/hydrogen.cc (working copy)
|
| @@ -5058,10 +5058,41 @@
|
| }
|
|
|
|
|
| -bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr,
|
| - HValue* receiver,
|
| - Handle<Map> receiver_map,
|
| - CheckType check_type) {
|
| +bool HGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra) {
|
| + if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
|
| + BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
|
| + switch (id) {
|
| + case kMathRound:
|
| + case kMathFloor:
|
| + case kMathAbs:
|
| + case kMathSqrt:
|
| + case kMathLog:
|
| + case kMathSin:
|
| + case kMathCos:
|
| + if (expr->arguments()->length() == 1) {
|
| + HValue* argument = Pop();
|
| + HValue* context = environment()->LookupContext();
|
| + Drop(1); // Receiver.
|
| + HUnaryMathOperation* op =
|
| + new(zone()) HUnaryMathOperation(context, argument, id);
|
| + op->set_position(expr->position());
|
| + if (drop_extra) Drop(1); // Optionally drop the function.
|
| + ast_context()->ReturnInstruction(op, expr->id());
|
| + return true;
|
| + }
|
| + break;
|
| + default:
|
| + // Not supported for inlining yet.
|
| + break;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| +bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
|
| + HValue* receiver,
|
| + Handle<Map> receiver_map,
|
| + CheckType check_type) {
|
| ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null());
|
| // Try to inline calls like Math.* as operations in the calling function.
|
| if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
|
| @@ -5155,7 +5186,7 @@
|
| case kMathRandom:
|
| if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
|
| AddCheckConstantFunction(expr, receiver, receiver_map, true);
|
| - Drop(1);
|
| + Drop(1); // Receiver.
|
| HValue* context = environment()->LookupContext();
|
| HGlobalObject* global_object = new(zone()) HGlobalObject(context);
|
| AddInstruction(global_object);
|
| @@ -5323,10 +5354,15 @@
|
| Handle<Map> receiver_map = (types == NULL || types->is_empty())
|
| ? Handle<Map>::null()
|
| : types->first();
|
| - if (TryInlineBuiltinFunction(expr,
|
| - receiver,
|
| - receiver_map,
|
| - expr->check_type())) {
|
| + if (TryInlineBuiltinMethodCall(expr,
|
| + receiver,
|
| + receiver_map,
|
| + expr->check_type())) {
|
| + if (FLAG_trace_inlining) {
|
| + PrintF("Inlining builtin ");
|
| + expr->target()->ShortPrint();
|
| + PrintF("\n");
|
| + }
|
| return;
|
| }
|
|
|
| @@ -5397,6 +5433,14 @@
|
| IsGlobalObject());
|
| environment()->SetExpressionStackAt(receiver_index, global_receiver);
|
|
|
| + if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop.
|
| + if (FLAG_trace_inlining) {
|
| + PrintF("Inlining builtin ");
|
| + expr->target()->ShortPrint();
|
| + PrintF("\n");
|
| + }
|
| + return;
|
| + }
|
| if (TryInline(expr)) return;
|
| call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
|
| argument_count));
|
| @@ -5423,6 +5467,16 @@
|
| PushAndAdd(receiver);
|
| CHECK_ALIVE(VisitExpressions(expr->arguments()));
|
| AddInstruction(new(zone()) HCheckFunction(function, expr->target()));
|
| +
|
| + if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
|
| + if (FLAG_trace_inlining) {
|
| + PrintF("Inlining builtin ");
|
| + expr->target()->ShortPrint();
|
| + PrintF("\n");
|
| + }
|
| + return;
|
| + }
|
| +
|
| if (TryInline(expr, true)) { // Drop function from environment.
|
| return;
|
| } else {
|
|
|