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

Unified Diff: src/hydrogen.cc

Issue 18918002: Turn polymorphic calls using the same prototype monomorphic. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 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') | no next file » | 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 21b83a2b2f011e185ea9c57bb211dd550e6757b2..62f342f9578f2f286da956100f83949a4907e595 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4941,6 +4941,17 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic(
}
+static bool CanLoadPropertyFromPrototype(Handle<Map> map,
+ Handle<Name> name,
+ LookupResult* lookup) {
+ if (map->has_named_interceptor()) return false;
+ if (map->is_dictionary_map()) return false;
+ map->LookupDescriptor(NULL, *name, lookup);
+ if (lookup->IsFound()) return false;
+ return true;
+}
+
+
HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
Property* expr,
HValue* object,
@@ -4990,17 +5001,12 @@ HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
// Second chance: the property is on the prototype and all maps have the
// same prototype.
Handle<Map> map(types->at(0));
- if (map->has_named_interceptor()) return NULL;
- if (map->is_dictionary_map()) return NULL;
+ if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL;
Handle<Object> prototype(map->prototype(), isolate());
for (count = 1; count < types->length(); ++count) {
Handle<Map> test_map(types->at(count));
- // Ensure the property is on the prototype, not the object itself.
- if (map->has_named_interceptor()) return NULL;
- if (test_map->is_dictionary_map()) return NULL;
- test_map->LookupDescriptor(NULL, *name, &lookup);
- if (lookup.IsFound()) return NULL;
+ if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL;
if (test_map->prototype() != *prototype) return NULL;
}
@@ -6358,14 +6364,60 @@ inline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) {
}
+bool HOptimizedGraphBuilder::TryCallPolymorphicAsMonomorphic(
+ Call* expr,
+ HValue* receiver,
+ SmallMapList* types,
+ Handle<String> name) {
+ if (types->length() > kMaxCallPolymorphism) return false;
+
+ Handle<Map> map(types->at(0));
+ LookupResult lookup(isolate());
+ if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return false;
+
+ Handle<Object> prototype(map->prototype(), isolate());
+ for (int count = 1; count < types->length(); ++count) {
+ Handle<Map> test_map(types->at(count));
+ if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return false;
+ if (test_map->prototype() != *prototype) return false;
+ }
+
+ if (!expr->ComputeTarget(map, name)) return false;
+
+ BuildCheckHeapObject(receiver);
+ AddInstruction(HCheckMaps::New(receiver, types, zone()));
+ AddCheckPrototypeMaps(expr->holder(), map);
+ if (FLAG_trace_inlining) {
+ Handle<JSFunction> caller = current_info()->closure();
+ SmartArrayPointer<char> caller_name =
+ caller->shared()->DebugName()->ToCString();
+ PrintF("Trying to inline the polymorphic call to %s from %s\n",
+ *name->ToCString(), *caller_name);
+ }
+
+ if (!TryInlineCall(expr)) {
+ int argument_count = expr->arguments()->length() + 1; // Includes receiver.
+ HCallConstantFunction* call =
+ new(zone()) HCallConstantFunction(expr->target(), argument_count);
+ call->set_position(expr->position());
+ PreProcessCall(call);
+ AddInstruction(call);
+ if (!ast_context()->IsEffect()) Push(call);
mvstanton 2013/07/10 12:48:14 Could you explain what is happening with this ast_
Toon Verwaest 2013/07/10 13:04:03 This is boilerplate code that's all over. I'll jus
+ AddSimulate(expr->id(), REMOVABLE_SIMULATE);
+ if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
+ }
+
+ return true;
+}
+
+
void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
Call* expr,
HValue* receiver,
SmallMapList* types,
Handle<String> name) {
- // TODO(ager): We should recognize when the prototype chains for different
- // maps are identical. In that case we can avoid repeatedly generating the
- // same prototype map checks.
+ if (TryCallPolymorphicAsMonomorphic(expr, receiver, types, name)) return;
+
int argument_count = expr->arguments()->length() + 1; // Includes receiver.
HBasicBlock* join = NULL;
FunctionSorter order[kMaxCallPolymorphism];
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698