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