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