Revision: 12986
Author:   [email protected]
Date:     Fri Nov 16 02:57:50 2012
Log:      Introduce helper functions to test parallel recompilation.

BUG=

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

Added:
 /branches/bleeding_edge/test/mjsunit/manual-parallel-recompile.js
Modified:
 /branches/bleeding_edge/src/execution.cc
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/optimizing-compiler-thread.cc
 /branches/bleeding_edge/src/optimizing-compiler-thread.h
 /branches/bleeding_edge/src/runtime-profiler.cc
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/manual-parallel-recompile.js Fri Nov 16 02:57:50 2012
@@ -0,0 +1,80 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --expose-gc
+// Flags: --parallel-recompilation --manual-parallel-recompilation
+
+function assertOptimized(fun) {
+ // This assertion takes --always-opt and --nocrankshaft flags into account.
+  assertTrue(%GetOptimizationStatus(fun) != 2);
+}
+
+function assertUnoptimized(fun) {
+  assertTrue(%GetOptimizationStatus(fun) != 1);
+}
+
+function f(x) {
+  var xx = x * x;
+  var xxstr = xx.toString();
+  return xxstr.length;
+}
+
+function g(x) {
+  var xxx = Math.sqrt(x) | 0;
+  var xxxstr = xxx.toString();
+  return xxxstr.length;
+}
+
+function k(x) {
+  return x * x;
+}
+
+f(g(1));
+f(g(2));
+assertUnoptimized(f);
+assertUnoptimized(g);
+
+%ForceParallelRecompile(f);
+%ForceParallelRecompile(g);
+assertUnoptimized(f);
+assertUnoptimized(g);
+
+var sum = 0;
+for (var i = 0; i < 10000; i++) sum += f(i) + g(i);
+gc();
+
+assertEquals(95274, sum);
+assertUnoptimized(f);
+assertUnoptimized(g);
+
+%InstallRecompiledCode(f);
+assertOptimized(f);
+assertUnoptimized(g);
+
+%InstallRecompiledCode("the rest");
+assertOptimized(g);
+
=======================================
--- /branches/bleeding_edge/src/execution.cc    Sun Oct 14 23:34:22 2012
+++ /branches/bleeding_edge/src/execution.cc    Fri Nov 16 02:57:50 2012
@@ -937,7 +937,8 @@
     }
     stack_guard->Continue(CODE_READY);
   }
-  if (!stack_guard->IsTerminateExecution()) {
+  if (!stack_guard->IsTerminateExecution() &&
+      !FLAG_manual_parallel_recompilation) {
     isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
   }

=======================================
--- /branches/bleeding_edge/src/flag-definitions.h      Fri Nov 16 02:38:10 2012
+++ /branches/bleeding_edge/src/flag-definitions.h      Fri Nov 16 02:57:50 2012
@@ -225,7 +225,7 @@
 DEFINE_bool(optimize_for_in, true,
             "optimize functions containing for-in loops")
 DEFINE_bool(opt_safe_uint32_operations, true,
- "allow uint32 values on optimize frames if they are used only in" + "allow uint32 values on optimize frames if they are used only in "
             "safe operations")

 DEFINE_bool(parallel_recompilation, false,
@@ -233,6 +233,9 @@
DEFINE_bool(trace_parallel_recompilation, false, "track parallel recompilation")
 DEFINE_int(parallel_recompilation_queue_length, 2,
            "the length of the parallel compilation queue")
+DEFINE_bool(manual_parallel_recompilation, false,
+            "disable automatic optimization")
+DEFINE_implication(manual_parallel_recompilation, parallel_recompilation)

 // Experimental profiler changes.
 DEFINE_bool(experimental_profiler, true, "enable all profiler experiments")
=======================================
--- /branches/bleeding_edge/src/optimizing-compiler-thread.cc Fri Jul 20 01:56:20 2012 +++ /branches/bleeding_edge/src/optimizing-compiler-thread.cc Fri Nov 16 02:57:50 2012
@@ -72,7 +72,13 @@
     USE(status);

     output_queue_.Enqueue(optimizing_compiler);
-    isolate_->stack_guard()->RequestCodeReadyEvent();
+    if (!FLAG_manual_parallel_recompilation) {
+      isolate_->stack_guard()->RequestCodeReadyEvent();
+    } else {
+      // In manual mode, do not trigger a code ready event.
+ // Instead, wait for the optimized functions to be installed manually.
+      output_queue_semaphore_->Signal();
+    }

     if (FLAG_trace_parallel_recompilation) {
       time_spent_compiling_ += OS::Ticks() - compiling_start;
@@ -99,6 +105,9 @@
   HandleScope handle_scope(isolate_);
   int functions_installed = 0;
   while (!output_queue_.IsEmpty()) {
+    if (FLAG_manual_parallel_recompilation) {
+      output_queue_semaphore_->Wait();
+    }
     OptimizingCompiler* compiler = NULL;
     output_queue_.Dequeue(&compiler);
     Compiler::InstallOptimizedCode(compiler);
@@ -108,6 +117,17 @@
     PrintF("  ** Installed %d function(s).\n", functions_installed);
   }
 }
+
+
+Handle<SharedFunctionInfo>
+    OptimizingCompilerThread::InstallNextOptimizedFunction() {
+  ASSERT(FLAG_manual_parallel_recompilation);
+  output_queue_semaphore_->Wait();
+  OptimizingCompiler* compiler = NULL;
+  output_queue_.Dequeue(&compiler);
+  Compiler::InstallOptimizedCode(compiler);
+  return compiler->info()->shared_info();
+}


 void OptimizingCompilerThread::QueueForOptimization(
=======================================
--- /branches/bleeding_edge/src/optimizing-compiler-thread.h Fri Jul 20 01:56:20 2012 +++ /branches/bleeding_edge/src/optimizing-compiler-thread.h Fri Nov 16 02:57:50 2012
@@ -29,8 +29,8 @@
 #define V8_OPTIMIZING_COMPILER_THREAD_H_

 #include "atomicops.h"
+#include "flags.h"
 #include "platform.h"
-#include "flags.h"
 #include "unbound-queue.h"

 namespace v8 {
@@ -38,6 +38,7 @@

 class HGraphBuilder;
 class OptimizingCompiler;
+class SharedFunctionInfo;

 class OptimizingCompilerThread : public Thread {
  public:
@@ -46,6 +47,7 @@
       isolate_(isolate),
       stop_semaphore_(OS::CreateSemaphore(0)),
       input_queue_semaphore_(OS::CreateSemaphore(0)),
+      output_queue_semaphore_(OS::CreateSemaphore(0)),
       time_spent_compiling_(0),
       time_spent_total_(0) {
     NoBarrier_Store(&stop_thread_, static_cast<AtomicWord>(false));
@@ -57,6 +59,9 @@
   void QueueForOptimization(OptimizingCompiler* optimizing_compiler);
   void InstallOptimizedFunctions();

+  // Wait for the next optimized function and install it.
+  Handle<SharedFunctionInfo> InstallNextOptimizedFunction();
+
   inline bool IsQueueAvailable() {
     // We don't need a barrier since we have a data dependency right
     // after.
@@ -77,6 +82,7 @@

   ~OptimizingCompilerThread() {
     delete input_queue_semaphore_;
+    delete output_queue_semaphore_;  // Only used for manual mode.
     delete stop_semaphore_;
   }

@@ -84,6 +90,7 @@
   Isolate* isolate_;
   Semaphore* stop_semaphore_;
   Semaphore* input_queue_semaphore_;
+  Semaphore* output_queue_semaphore_;
   UnboundQueue<OptimizingCompiler*> input_queue_;
   UnboundQueue<OptimizingCompiler*> output_queue_;
   volatile AtomicWord stop_thread_;
=======================================
--- /branches/bleeding_edge/src/runtime-profiler.cc     Thu Aug 16 04:40:03 2012
+++ /branches/bleeding_edge/src/runtime-profiler.cc     Fri Nov 16 02:57:50 2012
@@ -140,6 +140,9 @@

 void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) {
   ASSERT(function->IsOptimizable());
+  // If we are in manual mode, don't auto-optimize anything.
+  if (FLAG_manual_parallel_recompilation) return;
+
   if (FLAG_trace_opt) {
     PrintF("[marking ");
     function->PrintName();
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Fri Nov 16 00:38:11 2012
+++ /branches/bleeding_edge/src/runtime.cc      Fri Nov 16 02:57:50 2012
@@ -7990,7 +7990,36 @@
   HandleScope handle_scope(isolate);
   ASSERT(FLAG_parallel_recompilation);
   Compiler::RecompileParallel(args.at<JSFunction>(0));
-  return *isolate->factory()->undefined_value();
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ForceParallelRecompile) {
+  HandleScope handle_scope(isolate);
+ ASSERT(FLAG_parallel_recompilation && FLAG_manual_parallel_recompilation);
+  if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) {
+    return isolate->Throw(
+ *isolate->factory()->LookupAsciiSymbol("Recompile queue is full."));
+  }
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+ fun->ReplaceCode(isolate->builtins()->builtin(Builtins::kParallelRecompile));
+  Compiler::RecompileParallel(fun);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) {
+  HandleScope handle_scope(isolate);
+ ASSERT(FLAG_parallel_recompilation && FLAG_manual_parallel_recompilation);
+  CONVERT_ARG_HANDLE_CHECKED(HeapObject, arg, 0);
+ OptimizingCompilerThread* opt_thread = isolate->optimizing_compiler_thread();
+  if (!arg->IsJSFunction()) {
+    opt_thread->InstallOptimizedFunctions();
+  } else if (!JSFunction::cast(*arg)->IsOptimized()) {
+    Handle<SharedFunctionInfo> shared(JSFunction::cast(*arg)->shared());
+    while (*opt_thread->InstallNextOptimizedFunction() != *shared) { }
+  }
+  return isolate->heap()->undefined_value();
 }


=======================================
--- /branches/bleeding_edge/src/runtime.h       Mon Nov 12 06:54:29 2012
+++ /branches/bleeding_edge/src/runtime.h       Fri Nov 16 02:57:50 2012
@@ -85,7 +85,9 @@
   F(NewStrictArgumentsFast, 3, 1) \
   F(LazyCompile, 1, 1) \
   F(LazyRecompile, 1, 1) \
-  F(ParallelRecompile, 1, 1)     \
+  F(ParallelRecompile, 1, 1) \
+  F(ForceParallelRecompile, 1, 1) \
+  F(InstallRecompiledCode, 1, 1) \
   F(NotifyDeoptimized, 1, 1) \
   F(NotifyOSR, 0, 1) \
   F(DeoptimizeFunction, 1, 1) \

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

Reply via email to