Revision: 11498
Author:   [email protected]
Date:     Thu May  3 07:23:35 2012
Log:      Rollback of r11482 in trunk branch.

Sort functions when doing megamorphic dispatch/inlining so their order does not depend on the hash seed. Review URL: https://chromiumcodereview.appspot.com/10270032

[email protected]

Review URL: https://chromiumcodereview.appspot.com/10357005
http://code.google.com/p/v8/source/detail?r=11498

Modified:
 /trunk/src/hydrogen.cc
 /trunk/src/hydrogen.h
 /trunk/src/version.cc

=======================================
--- /trunk/src/hydrogen.cc      Thu May  3 02:06:43 2012
+++ /trunk/src/hydrogen.cc      Thu May  3 07:23:35 2012
@@ -5660,39 +5660,6 @@
         expr->holder()));
   }
 }
-
-
-class FunctionSorter {
- public:
- FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { }
-  FunctionSorter(int index, int ticks, int ast_length, int src_length)
-      : index_(index),
-        ticks_(ticks),
-        ast_length_(ast_length),
-        src_length_(src_length) { }
-
-  int index() const { return index_; }
-  int ticks() const { return ticks_; }
-  int ast_length() const { return ast_length_; }
-  int src_length() const { return src_length_; }
-
- private:
-  int index_;
-  int ticks_;
-  int ast_length_;
-  int src_length_;
-};
-
-
-static int CompareHotness(void const* a, void const* b) {
- FunctionSorter const* function1 = reinterpret_cast<FunctionSorter const*>(a); - FunctionSorter const* function2 = reinterpret_cast<FunctionSorter const*>(b);
-  int diff = function1->ticks() - function2->ticks();
-  if (diff != 0) return -diff;
-  diff = function1->ast_length() - function2->ast_length();
-  if (diff != 0) return diff;
-  return function1->src_length() - function2->src_length();
-}


 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
@@ -5703,73 +5670,51 @@
// maps are identical. In that case we can avoid repeatedly generating the
   // same prototype map checks.
int argument_count = expr->arguments()->length() + 1; // Includes receiver.
+  int count = 0;
   HBasicBlock* join = NULL;
-  FunctionSorter order[kMaxCallPolymorphism];
-  int ordered_functions = 0;
-  for (int i = 0;
-       i < types->length() && ordered_functions < kMaxCallPolymorphism;
-       ++i) {
+ for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) {
     Handle<Map> map = types->at(i);
     if (expr->ComputeTarget(map, name)) {
-      order[ordered_functions++] =
-          FunctionSorter(i,
- expr->target()->shared()->code()->profiler_ticks(),
-                         InliningAstSize(expr->target()),
-                         expr->target()->shared()->SourceSize());
-    }
-  }
-
-  qsort(reinterpret_cast<void*>(&order[0]),
-        ordered_functions,
-        sizeof(order[0]),
-        &CompareHotness);
-
-  for (int fn = 0; fn < ordered_functions; ++fn) {
-    int i = order[fn].index();
-    Handle<Map> map = types->at(i);
-    if (fn == 0) {
-      // Only needed once.
-      AddInstruction(new(zone()) HCheckNonSmi(receiver));
-      join = graph()->CreateBasicBlock();
-    }
-    HBasicBlock* if_true = graph()->CreateBasicBlock();
-    HBasicBlock* if_false = graph()->CreateBasicBlock();
-    HCompareMap* compare =
-        new(zone()) HCompareMap(receiver, map, if_true, if_false);
-    current_block()->Finish(compare);
-
-    set_current_block(if_true);
-    expr->ComputeTarget(map, name);
-    AddCheckConstantFunction(expr, receiver, map, false);
-    if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
-      Handle<JSFunction> caller = 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 (FLAG_polymorphic_inlining && TryInlineCall(expr)) {
-      // Trying to inline will signal that we should bailout from the
-      // entire compilation by setting stack overflow on the visitor.
-      if (HasStackOverflow()) return;
-    } else {
-      HCallConstantFunction* call =
- new(zone()) HCallConstantFunction(expr->target(), argument_count);
-      call->set_position(expr->position());
-      PreProcessCall(call);
-      AddInstruction(call);
-      if (!ast_context()->IsEffect()) Push(call);
-    }
-
-    if (current_block() != NULL) current_block()->Goto(join);
-    set_current_block(if_false);
+      if (count == 0) {
+        // Only needed once.
+        AddInstruction(new(zone()) HCheckNonSmi(receiver));
+        join = graph()->CreateBasicBlock();
+      }
+      ++count;
+      HBasicBlock* if_true = graph()->CreateBasicBlock();
+      HBasicBlock* if_false = graph()->CreateBasicBlock();
+      HCompareMap* compare =
+          new(zone()) HCompareMap(receiver, map, if_true, if_false);
+      current_block()->Finish(compare);
+
+      set_current_block(if_true);
+      AddCheckConstantFunction(expr, receiver, map, false);
+      if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
+        PrintF("Trying to inline the polymorphic call to %s\n",
+               *name->ToCString());
+      }
+      if (FLAG_polymorphic_inlining && TryInlineCall(expr)) {
+        // Trying to inline will signal that we should bailout from the
+        // entire compilation by setting stack overflow on the visitor.
+        if (HasStackOverflow()) return;
+      } else {
+        HCallConstantFunction* call =
+ new(zone()) HCallConstantFunction(expr->target(), argument_count);
+        call->set_position(expr->position());
+        PreProcessCall(call);
+        AddInstruction(call);
+        if (!ast_context()->IsEffect()) Push(call);
+      }
+
+      if (current_block() != NULL) current_block()->Goto(join);
+      set_current_block(if_false);
+    }
   }

// Finish up. Unconditionally deoptimize if we've handled all the maps we
   // know about and do not want to handle ones we've never seen.  Otherwise
   // use a generic IC.
- if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
+  if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
     current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
   } else {
     HValue* context = environment()->LookupContext();
@@ -5818,11 +5763,14 @@
 }


-static const int kNotInlinable = 1000000000;
-
-
-int HGraphBuilder::InliningAstSize(Handle<JSFunction> target) {
-  if (!FLAG_use_inlining) return kNotInlinable;
+bool HGraphBuilder::TryInline(CallKind call_kind,
+                              Handle<JSFunction> target,
+                              ZoneList<Expression*>* arguments,
+                              HValue* receiver,
+                              int ast_id,
+                              int return_id,
+                              ReturnHandlingFlag return_handling) {
+  if (!FLAG_use_inlining) return false;

   // Precondition: call is monomorphic and we have found a target with the
   // appropriate arity.
@@ -5834,42 +5782,24 @@
   if (target_shared->SourceSize() >
       Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) {
     TraceInline(target, caller, "target text too big");
-    return kNotInlinable;
+    return false;
   }

   // Target must be inlineable.
   if (!target->IsInlineable()) {
     TraceInline(target, caller, "target not inlineable");
-    return kNotInlinable;
+    return false;
   }
   if (target_shared->dont_inline() || target_shared->dont_optimize()) {
TraceInline(target, caller, "target contains unsupported syntax [early]");
-    return kNotInlinable;
+    return false;
   }

   int nodes_added = target_shared->ast_node_count();
-  return nodes_added;
-}
-
-
-bool HGraphBuilder::TryInline(CallKind call_kind,
-                              Handle<JSFunction> target,
-                              ZoneList<Expression*>* arguments,
-                              HValue* receiver,
-                              int ast_id,
-                              int return_id,
-                              ReturnHandlingFlag return_handling) {
-  int nodes_added = InliningAstSize(target);
-  if (nodes_added == kNotInlinable) return false;
-
-  Handle<JSFunction> caller = info()->closure();
-
if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) {
     TraceInline(target, caller, "target AST is too large [early]");
     return false;
   }
-
-  Handle<SharedFunctionInfo> target_shared(target->shared());

 #if !defined(V8_TARGET_ARCH_IA32)
   // Target must be able to use caller's context.
=======================================
--- /trunk/src/hydrogen.h       Thu May  3 02:06:43 2012
+++ /trunk/src/hydrogen.h       Thu May  3 07:23:35 2012
@@ -1010,7 +1010,6 @@
   // Try to optimize fun.apply(receiver, arguments) pattern.
   bool TryCallApply(Call* expr);

-  int InliningAstSize(Handle<JSFunction> target);
   bool TryInline(CallKind call_kind,
                  Handle<JSFunction> target,
                  ZoneList<Expression*>* arguments,
=======================================
--- /trunk/src/version.cc       Thu May  3 02:06:43 2012
+++ /trunk/src/version.cc       Thu May  3 07:23:35 2012
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     10
 #define BUILD_NUMBER      8
-#define PATCH_LEVEL       0
+#define PATCH_LEVEL       1
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to