Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index a7b8766eeeabf2bfdd9bdb830c1ebe39ae5cff3b..b0953957c26f93a62ed23e330b192244bbbcd9f0 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -5530,11 +5530,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) { |
| if (!callback->IsAccessorPair()) return false; |
| Object* getter = Handle<AccessorPair>::cast(callback)->getter(); |
| if (!getter->IsJSFunction()) return false; |
| - Handle<JSFunction> accessor = handle(JSFunction::cast(getter)); |
| - CallOptimization call_optimization(accessor); |
| - // TODO(dcarney): temporary hack unless crankshaft can handle api calls. |
| - if (call_optimization.is_simple_api_call()) return false; |
| - accessor_ = accessor; |
| + accessor_ = handle(JSFunction::cast(getter)); |
| } else if (lookup_.IsConstant()) { |
| constant_ = handle(lookup_.GetConstantFromMap(*map), isolate()); |
| } |
| @@ -5659,7 +5655,11 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadMonomorphic( |
| Push(checked_object); |
| if (FLAG_inline_accessors && |
| can_inline_accessor && |
| - TryInlineGetter(info->accessor(), ast_id, return_id)) { |
| + TryInlineGetter(info->accessor(), |
| + checked_object, |
| + info->map(), |
| + ast_id, |
| + return_id)) { |
| return NULL; |
| } |
| Add<HPushArgument>(Pop()); |
| @@ -7607,8 +7607,11 @@ bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, |
| bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, |
| + HValue * receiver, |
|
Toon Verwaest
2014/02/04 13:25:31
Remove space between HValue and *
|
| + Handle<Map> receiver_map, |
| BailoutId ast_id, |
| BailoutId return_id) { |
| + if (TryInlineApiGetter(getter, receiver, receiver_map, ast_id)) return true; |
| return TryInline(getter, |
| 0, |
| NULL, |
| @@ -7891,31 +7894,62 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
| bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr, |
| HValue* receiver) { |
| - return TryInlineApiCall( |
| - expr, receiver, Handle<Map>::null(), true); |
| + if (!expr->IsMonomorphic()) return false; |
|
Toon Verwaest
2014/02/04 13:25:31
These checks shouldn't be here, but rather in CanL
|
| + Handle<JSFunction> function = expr->target(); |
| + int argc = expr->arguments()->length(); |
| + Handle<Map> receiver_map = Handle<Map>::null(); |
| + return TryInlineApiCall(function, |
| + receiver, |
| + receiver_map, |
| + argc, |
| + expr->id(), |
| + kCallApiFunction); |
| } |
| bool HOptimizedGraphBuilder::TryInlineApiMethodCall(Call* expr, |
| HValue* receiver, |
| Handle<Map> receiver_map) { |
| - return TryInlineApiCall(expr, receiver, receiver_map, false); |
| -} |
| - |
| -bool HOptimizedGraphBuilder::TryInlineApiCall(Call* expr, |
| - HValue* receiver, |
| - Handle<Map> receiver_map, |
| - bool is_function_call) { |
| if (!expr->IsMonomorphic()) return false; |
| - CallOptimization optimization(expr->target()); |
| + Handle<JSFunction> function = expr->target(); |
| + int argc = expr->arguments()->length(); |
| + return TryInlineApiCall(function, |
| + receiver, |
| + receiver_map, |
| + argc, |
| + expr->id(), |
| + kCallApiMethod); |
| +} |
| + |
| + |
| +bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function, |
| + HValue* receiver, |
| + Handle<Map> receiver_map, |
| + BailoutId ast_id) { |
| + return TryInlineApiCall(function, |
| + receiver, |
| + receiver_map, |
| + 0, |
| + ast_id, |
| + kCallApiGetter); |
| +} |
| + |
| + |
| +bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function, |
| + HValue* receiver, |
| + Handle<Map> receiver_map, |
| + int argc, |
| + BailoutId ast_id, |
| + ApiCallType call_type) { |
| + CallOptimization optimization(function); |
| if (!optimization.is_simple_api_call()) return false; |
| Handle<Map> holder_map; |
| - if (is_function_call) { |
| + if (call_type == kCallApiFunction) { |
| // Cannot embed a direct reference to the global proxy map |
| // as it maybe dropped on deserialization. |
| CHECK(!Serializer::enabled()); |
| - receiver_map = Handle<Map>( |
| - expr->target()->context()->global_object()->global_receiver()->map()); |
| + receiver_map = handle( |
| + function->context()->global_object()->global_receiver()->map()); |
| } |
| CallOptimization::HolderLookup holder_lookup = |
| CallOptimization::kHolderNotFound; |
| @@ -7925,13 +7959,17 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Call* expr, |
| if (FLAG_trace_inlining) { |
| PrintF("Inlining api function "); |
| - expr->target()->ShortPrint(); |
| + function->ShortPrint(); |
| PrintF("\n"); |
| } |
| - const int argc = expr->arguments()->length(); |
| - // Includes receiver. |
| - PushArgumentsFromEnvironment(argc + 1); |
| + if (call_type == kCallApiGetter) { |
| + ASSERT_EQ(0, argc); |
| + Add<HPushArgument>(Pop()); // Receiver. |
| + } else { |
| + // Includes receiver. |
| + PushArgumentsFromEnvironment(argc + 1); |
| + } |
| // Need to ensure the chain between receiver and api_holder is intact |
| AddCheckMap(receiver, receiver_map); |
| @@ -7964,8 +8002,7 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Call* expr, |
| HValue* api_function_address = Add<HConstant>(ExternalReference(ref)); |
| HValue* op_vals[] = { |
| - // callee |
| - Add<HConstant>(expr->target()), |
| + Add<HConstant>(function), |
| call_data, |
| holder, |
| api_function_address, |
| @@ -7986,8 +8023,15 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Call* expr, |
| code_value, argc + 1, descriptor, |
| Vector<HValue*>(op_vals, descriptor->environment_length())); |
| - Drop(1); // Drop function. |
| - ast_context()->ReturnInstruction(call, expr->id()); |
| + switch (call_type) { |
| + case kCallApiFunction: |
| + case kCallApiMethod: |
| + Drop(1); // Drop function. |
| + break; |
| + case kCallApiGetter: |
| + break; |
| + } |
| + ast_context()->ReturnInstruction(call, ast_id); |
| return true; |
| } |