Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(459)

Unified Diff: src/hydrogen.cc

Issue 146023004: inline api getters in crankshaft (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 4b4a158d4f5de65fbce4f8fa9781c2d4d757bf7b..8caeab7659ae2afa237329b83f780468de6acb75 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -5361,7 +5361,8 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible(
if (info->has_holder()) return false;
if (lookup_.IsPropertyCallbacks()) {
- return accessor_.is_identical_to(info->accessor_);
+ return accessor_.is_identical_to(info->accessor_) &&
+ api_holder_.is_identical_to(info->api_holder_);
}
if (lookup_.IsConstant()) {
@@ -5407,9 +5408,20 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
: Handle<AccessorPair>::cast(callback)->setter();
if (!raw_accessor->IsJSFunction()) return false;
Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor));
- CallOptimization call_optimization(accessor);
- // TODO(dcarney): temporary hack unless crankshaft can handle api calls.
- if (call_optimization.is_simple_api_call()) return false;
+ if (accessor->shared()->IsApiFunction()) {
+ CallOptimization call_optimization(accessor);
+ if (!call_optimization.is_simple_api_call()) return false;
+ CallOptimization::HolderLookup holder_lookup;
+ api_holder_ = call_optimization.LookupHolderOfExpectedType(
+ map, &holder_lookup);
+ switch (holder_lookup) {
+ case CallOptimization::kHolderNotFound:
+ return false;
+ case CallOptimization::kHolderIsReceiver:
+ case CallOptimization::kHolderFound:
+ break;
+ }
+ }
accessor_ = accessor;
} else if (lookup_.IsConstant()) {
constant_ = handle(lookup_.GetConstantFromMap(*map), isolate());
@@ -5572,7 +5584,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess(
return New<HCallFunction>(function, argument_count, WRAP_AND_CALL);
} else if (FLAG_inline_accessors && can_inline_accessor) {
bool success = info->IsLoad()
- ? TryInlineGetter(info->accessor(), ast_id, return_id)
+ ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
: TryInlineSetter(info->accessor(), ast_id, return_id, value);
if (success) return NULL;
}
@@ -7394,8 +7406,10 @@ bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr,
bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
+ Handle<Map> receiver_map,
BailoutId ast_id,
BailoutId return_id) {
+ if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true;
return TryInline(getter,
0,
NULL,
@@ -7678,54 +7692,102 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr,
HValue* receiver) {
- return TryInlineApiCall(
- expr, receiver, Handle<Map>::null(), true);
+ Handle<JSFunction> function = expr->target();
+ int argc = expr->arguments()->length();
+ SmallMapList receiver_maps;
+ return TryInlineApiCall(function,
+ receiver,
+ &receiver_maps,
+ 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());
+bool HOptimizedGraphBuilder::TryInlineApiMethodCall(
+ Call* expr,
+ HValue* receiver,
+ SmallMapList* receiver_maps) {
+ Handle<JSFunction> function = expr->target();
+ int argc = expr->arguments()->length();
+ return TryInlineApiCall(function,
+ receiver,
+ receiver_maps,
+ argc,
+ expr->id(),
+ kCallApiMethod);
+}
+
+
+bool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function,
+ Handle<Map> receiver_map,
+ BailoutId ast_id) {
+ SmallMapList receiver_maps(1, zone());
+ receiver_maps.Add(receiver_map, zone());
+ return TryInlineApiCall(function,
+ NULL, // Receiver is on expression stack.
+ &receiver_maps,
+ 0,
+ ast_id,
+ kCallApiGetter);
+}
+
+
+bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function,
+ HValue* receiver,
+ SmallMapList* receiver_maps,
+ 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());
+ ASSERT_EQ(0, receiver_maps->length());
+ receiver_maps->Add(handle(
+ function->context()->global_object()->global_receiver()->map()),
+ zone());
}
CallOptimization::HolderLookup holder_lookup =
CallOptimization::kHolderNotFound;
Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
- receiver_map, &holder_lookup);
+ receiver_maps->first(), &holder_lookup);
if (holder_lookup == CallOptimization::kHolderNotFound) return false;
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);
-
- // Need to ensure the chain between receiver and api_holder is intact
- AddCheckMap(receiver, receiver_map);
- if (holder_lookup == CallOptimization::kHolderFound) {
- AddCheckPrototypeMaps(api_holder, receiver_map);
- } else {
- ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver);
+ bool drop_extra = false;
+ switch (call_type) {
+ case kCallApiFunction:
+ case kCallApiMethod:
+ // Need to check that none of the receiver maps could have changed.
+ Add<HCheckMaps>(receiver, receiver_maps);
+ // Need to ensure the chain between receiver and api_holder is intact.
+ if (holder_lookup == CallOptimization::kHolderFound) {
+ AddCheckPrototypeMaps(api_holder, receiver_maps->first());
+ } else {
+ ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver);
+ }
+ // Includes receiver.
+ PushArgumentsFromEnvironment(argc + 1);
+ // Drop function after call.
+ drop_extra = true;
+ break;
+ case kCallApiGetter:
+ // Receiver and prototype chain cannot have changed.
+ ASSERT_EQ(0, argc);
+ ASSERT_EQ(NULL, receiver);
+ // Receiver is on expression stack.
+ receiver = Pop();
+ Add<HPushArgument>(receiver);
+ break;
}
HValue* holder = NULL;
@@ -7751,8 +7813,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,
@@ -7773,8 +7834,8 @@ 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());
+ if (drop_extra) Drop(1); // Drop function.
+ ast_context()->ReturnInstruction(call, ast_id);
return true;
}
@@ -7923,7 +7984,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
}
return;
}
- if (TryInlineApiMethodCall(expr, receiver, map)) return;
+ if (TryInlineApiMethodCall(expr, receiver, types)) return;
// Wrap the receiver if necessary.
if (NeedsWrappingFor(ToType(types->first()), known_function)) {
« no previous file with comments | « src/hydrogen.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698