Inhibit OSR for big functions.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 14 Jun 2013 11:35:00 +0000 (11:35 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 14 Jun 2013 11:35:00 +0000 (11:35 +0000)
R=jkummerow@chromium.org
BUG=

Review URL: https://chromiumcodereview.appspot.com/17030008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15147 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/full-codegen-arm.cc
src/full-codegen.h
src/ia32/full-codegen-ia32.cc
src/mips/full-codegen-mips.cc
src/runtime-profiler.cc
src/runtime-profiler.h
src/x64/full-codegen-x64.cc

index 7c2d4743f08e803a40b0415cedf91e972cfdc89c..77d5524aa9aa63fcaae95214b74eb7a493393632 100644 (file)
@@ -361,7 +361,7 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
     ASSERT(back_edge_target->is_bound());
     int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
     weight = Min(kMaxBackEdgeWeight,
-                 Max(1, distance / kBackEdgeDistanceUnit));
+                 Max(1, distance / kCodeSizeMultiplier));
   }
   EmitProfilingCounterDecrement(weight);
   __ b(pl, &ok);
@@ -404,7 +404,7 @@ void FullCodeGenerator::EmitReturnSequence() {
       } else if (FLAG_weighted_back_edges) {
         int distance = masm_->pc_offset();
         weight = Min(kMaxBackEdgeWeight,
-                     Max(1, distance / kBackEdgeDistanceUnit));
+                     Max(1, distance / kCodeSizeMultiplier));
       }
       EmitProfilingCounterDecrement(weight);
       Label ok;
index 969a98d93a1ef9b6e88d949c8c7a6e8207ac4649..dc5ac6af272e63ead3d922ff44ec2f20d04d60e5 100644 (file)
@@ -123,14 +123,15 @@ class FullCodeGenerator: public AstVisitor {
 
   static const int kMaxBackEdgeWeight = 127;
 
+  // Platform-specific code size multiplier.
 #if V8_TARGET_ARCH_IA32
-  static const int kBackEdgeDistanceUnit = 100;
+  static const int kCodeSizeMultiplier = 100;
 #elif V8_TARGET_ARCH_X64
-  static const int kBackEdgeDistanceUnit = 162;
+  static const int kCodeSizeMultiplier = 162;
 #elif V8_TARGET_ARCH_ARM
-  static const int kBackEdgeDistanceUnit = 142;
+  static const int kCodeSizeMultiplier = 142;
 #elif V8_TARGET_ARCH_MIPS
-  static const int kBackEdgeDistanceUnit = 142;
+  static const int kCodeSizeMultiplier = 142;
 #else
 #error Unsupported target architecture.
 #endif
index 24054c6ce0b57948f2cdc5122b2e36ea7d5b1303..54e9eaf1d60969a65cd0ac17dd852e1a3bcf411e 100644 (file)
@@ -342,7 +342,7 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
     ASSERT(back_edge_target->is_bound());
     int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
     weight = Min(kMaxBackEdgeWeight,
-                 Max(1, distance / kBackEdgeDistanceUnit));
+                 Max(1, distance / kCodeSizeMultiplier));
   }
   EmitProfilingCounterDecrement(weight);
   __ j(positive, &ok, Label::kNear);
@@ -384,7 +384,7 @@ void FullCodeGenerator::EmitReturnSequence() {
       } else if (FLAG_weighted_back_edges) {
         int distance = masm_->pc_offset();
         weight = Min(kMaxBackEdgeWeight,
-                     Max(1, distance / kBackEdgeDistanceUnit));
+                     Max(1, distance / kCodeSizeMultiplier));
       }
       EmitProfilingCounterDecrement(weight);
       Label ok;
index 64d0e39aa4969c9d1ac0f2d6b8fc1ce5cb9c25e6..df83019f15e4a9c349d425da19257592618f3d13 100644 (file)
@@ -363,7 +363,7 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
     ASSERT(back_edge_target->is_bound());
     int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
     weight = Min(kMaxBackEdgeWeight,
-                 Max(1, distance / kBackEdgeDistanceUnit));
+                 Max(1, distance / kCodeSizeMultiplier));
   }
   EmitProfilingCounterDecrement(weight);
   __ slt(at, a3, zero_reg);
@@ -406,7 +406,7 @@ void FullCodeGenerator::EmitReturnSequence() {
       } else if (FLAG_weighted_back_edges) {
         int distance = masm_->pc_offset();
         weight = Min(kMaxBackEdgeWeight,
-                     Max(1, distance / kBackEdgeDistanceUnit));
+                     Max(1, distance / kCodeSizeMultiplier));
       }
       EmitProfilingCounterDecrement(weight);
       Label ok;
index c4b79b11b5ef8d2537cf96b8b6626b110699269c..9b7dd34ccd1d61c6fdd6075cdd4de61c24c4ffd1 100644 (file)
@@ -80,11 +80,17 @@ STATIC_ASSERT(kProfilerTicksBeforeOptimization < 256);
 STATIC_ASSERT(kProfilerTicksBeforeReenablingOptimization < 256);
 STATIC_ASSERT(kTicksWhenNotEnoughTypeInfo < 256);
 
+// Maximum size in bytes of generate code for a function to allow OSR.
+static const int kOSRCodeSizeAllowanceBase =
+    100 * FullCodeGenerator::kCodeSizeMultiplier;
+
+static const int kOSRCodeSizeAllowancePerTick =
+    3 * FullCodeGenerator::kCodeSizeMultiplier;
 
 // Maximum size in bytes of generated code for a function to be optimized
 // the very first time it is seen on the stack.
 static const int kMaxSizeEarlyOpt =
-    5 * FullCodeGenerator::kBackEdgeDistanceUnit;
+    5 * FullCodeGenerator::kCodeSizeMultiplier;
 
 
 RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
@@ -100,14 +106,13 @@ RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
 }
 
 
-static void GetICCounts(JSFunction* function,
+static void GetICCounts(Code* shared_code,
                         int* ic_with_type_info_count,
                         int* ic_total_count,
                         int* percentage) {
   *ic_total_count = 0;
   *ic_with_type_info_count = 0;
-  Object* raw_info =
-      function->shared()->code()->type_feedback_info();
+  Object* raw_info = shared_code->type_feedback_info();
   if (raw_info->IsTypeFeedbackInfo()) {
     TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info);
     *ic_with_type_info_count = info->ic_with_type_info_count();
@@ -128,7 +133,7 @@ void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) {
     PrintF(" for recompilation, reason: %s", reason);
     if (FLAG_type_info_threshold > 0) {
       int typeinfo, total, percentage;
-      GetICCounts(function, &typeinfo, &total, &percentage);
+      GetICCounts(function->shared()->code(), &typeinfo, &total, &percentage);
       PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total, percentage);
     }
     PrintF("]\n");
@@ -274,12 +279,20 @@ void RuntimeProfiler::OptimizeNow() {
         (function->IsMarkedForLazyRecompilation() ||
          function->IsMarkedForParallelRecompilation() ||
          function->IsOptimized())) {
-      int nesting = shared_code->allow_osr_at_loop_nesting_level();
-      if (nesting < Code::kMaxLoopNestingMarker) {
-        int new_nesting = nesting + 1;
-        shared_code->set_allow_osr_at_loop_nesting_level(new_nesting);
-        AttemptOnStackReplacement(function);
+      int ticks = shared_code->profiler_ticks();
+      int allowance = kOSRCodeSizeAllowanceBase +
+                      ticks * kOSRCodeSizeAllowancePerTick;
+      if (shared_code->CodeSize() > allowance) {
+        if (ticks < 255) shared_code->set_profiler_ticks(ticks + 1);
+      } else {
+        int nesting = shared_code->allow_osr_at_loop_nesting_level();
+        if (nesting < Code::kMaxLoopNestingMarker) {
+          int new_nesting = nesting + 1;
+          shared_code->set_allow_osr_at_loop_nesting_level(new_nesting);
+          AttemptOnStackReplacement(function);
+        }
       }
+      continue;
     }
 
     // Only record top-level code on top of the execution stack and
@@ -313,7 +326,7 @@ void RuntimeProfiler::OptimizeNow() {
 
       if (ticks >= kProfilerTicksBeforeOptimization) {
         int typeinfo, total, percentage;
-        GetICCounts(function, &typeinfo, &total, &percentage);
+        GetICCounts(shared_code, &typeinfo, &total, &percentage);
         if (percentage >= FLAG_type_info_threshold) {
           // If this particular function hasn't had any ICs patched for enough
           // ticks, optimize it now.
index 1bf9aa87851fba52a0c07b1538aecd9657822544..46da38155f246c7893ade77a64630c510179d514 100644 (file)
@@ -75,6 +75,8 @@ class RuntimeProfiler {
 
   void AddSample(JSFunction* function, int weight);
 
+  bool CodeSizeOKForOSR(Code* shared_code);
+
   Isolate* isolate_;
 
   int sampler_threshold_;
index 3b1fc93b5f2795130617761cd4ae9cfd5d72e993..e5d190ade934156e0e62fbde8150e853ed5956e4 100644 (file)
@@ -337,7 +337,7 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
     ASSERT(back_edge_target->is_bound());
     int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
     weight = Min(kMaxBackEdgeWeight,
-                 Max(1, distance / kBackEdgeDistanceUnit));
+                 Max(1, distance / kCodeSizeMultiplier));
   }
   EmitProfilingCounterDecrement(weight);
   __ j(positive, &ok, Label::kNear);
@@ -378,7 +378,7 @@ void FullCodeGenerator::EmitReturnSequence() {
       } else if (FLAG_weighted_back_edges) {
         int distance = masm_->pc_offset();
         weight = Min(kMaxBackEdgeWeight,
-                     Max(1, distance / kBackEdgeDistanceUnit));
+                     Max(1, distance / kCodeSizeMultiplier));
       }
       EmitProfilingCounterDecrement(weight);
       Label ok;