Chromium Code Reviews| Index: src/hydrogen.cc |
| =================================================================== |
| --- src/hydrogen.cc (revision 10631) |
| +++ src/hydrogen.cc (working copy) |
| @@ -5058,10 +5058,42 @@ |
| } |
| -bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr, |
| - HValue* receiver, |
| - Handle<Map> receiver_map, |
| - CheckType check_type) { |
| +bool HGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra) { |
|
Vyacheslav Egorov (Chromium)
2012/02/08 10:50:59
maybe it's time to have enum for drop_extra so it
|
| + if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
| + BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
| + int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
| + switch (id) { |
| + case kMathRound: |
| + case kMathFloor: |
| + case kMathAbs: |
| + case kMathSqrt: |
| + case kMathLog: |
| + case kMathSin: |
| + case kMathCos: |
| + if (argument_count == 2) { |
|
Vyacheslav Egorov (Chromium)
2012/02/08 10:50:59
I think you can just use expr->arguments()->length
fschneider
2012/02/08 11:45:18
Done.
|
| + 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. |
|
Vyacheslav Egorov (Chromium)
2012/02/08 10:50:59
It would be good to add test case that ensures tha
fschneider
2012/02/08 11:45:18
Done.
|
| + 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 +5187,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 +5355,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 +5434,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 +5468,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 { |