Revision: 15593
Author: [email protected]
Date: Wed Jul 10 06:05:41 2013
Log: Turn polymorphic calls using the same prototype monomorphic.
[email protected]
Review URL: https://chromiumcodereview.appspot.com/18918002
http://code.google.com/p/v8/source/detail?r=15593
Modified:
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Wed Jul 10 05:19:02 2013
+++ /branches/bleeding_edge/src/hydrogen.cc Wed Jul 10 06:05:41 2013
@@ -4941,6 +4941,17 @@
// No luck, do a generic store.
return BuildStoreNamedGeneric(object, name, value);
}
+
+
+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(
@@ -4992,17 +5003,12 @@
// 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;
}
@@ -6360,15 +6366,61 @@
return lhs.src_length() < rhs.src_length();
}
+
+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);
+ 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];
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Wed Jul 10 05:19:02 2013
+++ /branches/bleeding_edge/src/hydrogen.h Wed Jul 10 06:05:41 2013
@@ -1759,6 +1759,10 @@
HValue* receiver,
SmallMapList* types,
Handle<String> name);
+ bool TryCallPolymorphicAsMonomorphic(Call* expr,
+ HValue* receiver,
+ SmallMapList* types,
+ Handle<String> name);
void HandleLiteralCompareTypeof(CompareOperation* expr,
HTypeof* typeof_expr,
Handle<String> check);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.