Revision: 13827
Author:   [email protected]
Date:     Tue Mar  5 08:22:08 2013
Log:      Details wrt parallel recompilation.

This includes:
- actually release handles kept by compilation info when compilation completes.
- do not use parallel recompilation on single core CPUs.
- artificially delay parallel recompilation for debugging.
- fix outdated assertions wrt optimization status.
- add "parallel" option to %OptimizeFunctionOnNextCall.

[email protected]
BUG=

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

Added:
 /branches/bleeding_edge/test/mjsunit/parallel-optimize-disabled.js
Modified:
 /branches/bleeding_edge/src/compiler.cc
 /branches/bleeding_edge/src/compiler.h
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/isolate.cc
 /branches/bleeding_edge/src/isolate.h
 /branches/bleeding_edge/src/optimizing-compiler-thread.cc
 /branches/bleeding_edge/src/optimizing-compiler-thread.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/smart-pointers.h

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/parallel-optimize-disabled.js Tue Mar 5 08:22:08 2013
@@ -0,0 +1,46 @@
+// Copyright 2013 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: --nodead-code-elimination --parallel-recompilation
+// Flags: --allow-natives-syntax
+
+function g() {  // g() cannot be optimized.
+  const x = 1;
+  x++;
+}
+
+function f(x) {
+  g();
+}
+
+f();
+f();
+%OptimizeFunctionOnNextCall(g, "parallel");
+%OptimizeFunctionOnNextCall(f);
+f(0);  // g() is disabled for optimization on inlining attempt.
+g();  // Attempt to optimize g() should not run into any assertion.
+
=======================================
--- /branches/bleeding_edge/src/compiler.cc     Wed Feb 27 06:45:59 2013
+++ /branches/bleeding_edge/src/compiler.cc     Tue Mar  5 08:22:08 2013
@@ -963,6 +963,17 @@

void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
   SmartPointer<CompilationInfo> info(optimizing_compiler->info());
+  // Function may have been optimized meanwhile by OSR.
+  if (FLAG_use_osr) {
+    // Function may have already been optimized meanwhile by OSR.
+    if (!info->code().is_null() &&
+        info->code()->kind() == Code::OPTIMIZED_FUNCTION) {
+      return;
+    }
+    // OSR may also have caused optimization to be disabled.
+    if (info->shared_info()->optimization_disabled()) return;
+  }
+
   Isolate* isolate = info->isolate();
   VMState state(isolate, PARALLEL_COMPILER);
   Logger::TimerEventScope timer(
=======================================
--- /branches/bleeding_edge/src/compiler.h      Mon Feb 25 06:46:09 2013
+++ /branches/bleeding_edge/src/compiler.h      Tue Mar  5 08:22:08 2013
@@ -49,7 +49,7 @@
   CompilationInfo(Handle<JSFunction> closure, Zone* zone);
   CompilationInfo(HydrogenCodeStub* stub, Isolate* isolate, Zone* zone);

-  virtual ~CompilationInfo();
+  ~CompilationInfo();

   Isolate* isolate() {
     ASSERT(Isolate::Current() == isolate_);
@@ -349,8 +349,6 @@
 // Zone on construction and deallocates it on exit.
 class CompilationInfoWithZone: public CompilationInfo {
  public:
-  INLINE(void* operator new(size_t size)) { return Malloced::New(size); }
-
   explicit CompilationInfoWithZone(Handle<Script> script)
       : CompilationInfo(script, &zone_),
         zone_(script->GetIsolate()),
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h      Fri Mar  1 08:06:34 2013
+++ /branches/bleeding_edge/src/flag-definitions.h      Tue Mar  5 08:22:08 2013
@@ -248,6 +248,8 @@
DEFINE_bool(trace_parallel_recompilation, false, "track parallel recompilation")
 DEFINE_int(parallel_recompilation_queue_length, 2,
            "the length of the parallel compilation queue")
+DEFINE_int(parallel_recompilation_delay, 0,
+           "artificial compilation delay in ms")
 DEFINE_bool(manual_parallel_recompilation, false,
             "disable automatic optimization")
 DEFINE_implication(manual_parallel_recompilation, parallel_recompilation)
=======================================
--- /branches/bleeding_edge/src/isolate.cc      Thu Feb 28 09:03:34 2013
+++ /branches/bleeding_edge/src/isolate.cc      Tue Mar  5 08:22:08 2013
@@ -1772,6 +1772,8 @@
   if (state_ == INITIALIZED) {
     TRACE_ISOLATE(deinit);

+    if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Stop();
+
     if (FLAG_sweeper_threads > 0) {
       for (int i = 0; i < FLAG_sweeper_threads; i++) {
         sweeper_thread_[i]->Stop();
@@ -1787,8 +1789,6 @@
       }
       delete[] marking_thread_;
     }
-
-    if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Stop();

     if (FLAG_hydrogen_stats) HStatistics::Instance()->Print();

@@ -2198,6 +2198,11 @@
     FLAG_concurrent_sweeping = false;
     FLAG_parallel_sweeping = false;
   }
+  if (FLAG_parallel_recompilation &&
+      SystemThreadManager::NumberOfParallelSystemThreads(
+          SystemThreadManager::PARALLEL_RECOMPILATION) == 0) {
+    FLAG_parallel_recompilation = false;
+  }
   return true;
 }

=======================================
--- /branches/bleeding_edge/src/isolate.h       Tue Mar  5 02:48:16 2013
+++ /branches/bleeding_edge/src/isolate.h       Tue Mar  5 08:22:08 2013
@@ -292,7 +292,8 @@
   enum ParallelSystemComponent {
     PARALLEL_SWEEPING,
     CONCURRENT_SWEEPING,
-    PARALLEL_MARKING
+    PARALLEL_MARKING,
+    PARALLEL_RECOMPILATION
   };

   static int NumberOfParallelSystemThreads(ParallelSystemComponent type);
=======================================
--- /branches/bleeding_edge/src/optimizing-compiler-thread.cc Fri Jan 25 07:54:19 2013 +++ /branches/bleeding_edge/src/optimizing-compiler-thread.cc Tue Mar 5 08:22:08 2013
@@ -50,6 +50,11 @@
     input_queue_semaphore_->Wait();
     Logger::TimerEventScope timer(
         isolate_, Logger::TimerEventScope::v8_recompile_parallel);
+
+    if (FLAG_parallel_recompilation_delay != 0) {
+      OS::Sleep(FLAG_parallel_recompilation_delay);
+    }
+
     if (Acquire_Load(&stop_thread_)) {
       stop_semaphore_->Signal();
       if (FLAG_trace_parallel_recompilation) {
@@ -61,19 +66,8 @@
     int64_t compiling_start = 0;
     if (FLAG_trace_parallel_recompilation) compiling_start = OS::Ticks();

-    Heap::RelocationLock relocation_lock(isolate_->heap());
-    OptimizingCompiler* optimizing_compiler = NULL;
-    input_queue_.Dequeue(&optimizing_compiler);
-    Barrier_AtomicIncrement(&queue_length_, static_cast<Atomic32>(-1));
+    CompileNext();

-    ASSERT(!optimizing_compiler->info()->closure()->IsOptimized());
-
- OptimizingCompiler::Status status = optimizing_compiler->OptimizeGraph();
-    ASSERT(status != OptimizingCompiler::FAILED);
-    // Prevent an unused-variable error in release mode.
-    USE(status);
-
-    output_queue_.Enqueue(optimizing_compiler);
     if (!FLAG_manual_parallel_recompilation) {
       isolate_->stack_guard()->RequestCodeReadyEvent();
     } else {
@@ -87,6 +81,27 @@
     }
   }
 }
+
+
+void OptimizingCompilerThread::CompileNext() {
+  Heap::RelocationLock relocation_lock(isolate_->heap());
+  OptimizingCompiler* optimizing_compiler = NULL;
+  input_queue_.Dequeue(&optimizing_compiler);
+  Barrier_AtomicIncrement(&queue_length_, static_cast<Atomic32>(-1));
+
+  // Function may have been optimized meanwhile by OSR.
+  if (FLAG_use_osr &&
+      optimizing_compiler->info()->closure()->IsOptimized()) {
+    return;
+  }
+
+  OptimizingCompiler::Status status = optimizing_compiler->OptimizeGraph();
+  ASSERT(status != OptimizingCompiler::FAILED);
+  // Prevent an unused-variable error in release mode.
+  USE(status);
+
+  output_queue_.Enqueue(optimizing_compiler);
+}


 void OptimizingCompilerThread::Stop() {
@@ -94,6 +109,20 @@
   input_queue_semaphore_->Signal();
   stop_semaphore_->Wait();

+  if (FLAG_parallel_recompilation_delay != 0) {
+ // Execution ended before we managed to compile and install the remaining + // functions in the queue. We still want to do that for debugging though.
+    // At this point the optimizing thread already stopped, so we finish
+    // processing the queue in the main thread.
+    InstallOptimizedFunctions();
+    // Barrier when loading queue length is not necessary since the write
+    // happens in CompileNext on the same thread.
+    while (NoBarrier_Load(&queue_length_) > 0) {
+      CompileNext();
+      InstallOptimizedFunctions();
+    }
+  }
+
   if (FLAG_trace_parallel_recompilation) {
     double compile_time = static_cast<double>(time_spent_compiling_);
     double total_time = static_cast<double>(time_spent_total_);
@@ -123,11 +152,13 @@

 Handle<SharedFunctionInfo>
     OptimizingCompilerThread::InstallNextOptimizedFunction() {
-  ASSERT(FLAG_manual_parallel_recompilation);
+  ASSERT(FLAG_manual_parallel_recompilation ||
+         FLAG_parallel_recompilation_delay != 0);
   output_queue_semaphore_->Wait();
   OptimizingCompiler* compiler = NULL;
   output_queue_.Dequeue(&compiler);
-  Handle<SharedFunctionInfo> shared = compiler->info()->shared_info();
+  // Copy a handle from deferred handle scope to the normal handle scope.
+  Handle<SharedFunctionInfo> shared(*compiler->info()->shared_info());
   Compiler::InstallOptimizedCode(compiler);
   return shared;
 }
=======================================
--- /branches/bleeding_edge/src/optimizing-compiler-thread.h Tue Dec 18 08:25:45 2012 +++ /branches/bleeding_edge/src/optimizing-compiler-thread.h Tue Mar 5 08:22:08 2013
@@ -59,6 +59,7 @@

   void Run();
   void Stop();
+  void CompileNext();
   void QueueForOptimization(OptimizingCompiler* optimizing_compiler);
   void InstallOptimizedFunctions();

=======================================
--- /branches/bleeding_edge/src/runtime.cc      Mon Mar  4 09:53:40 2013
+++ /branches/bleeding_edge/src/runtime.cc      Tue Mar  5 08:22:08 2013
@@ -7682,31 +7682,36 @@
 }


-RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  Handle<JSFunction> function = args.at<JSFunction>(0);
-
+bool AllowOptimization(Isolate* isolate, Handle<JSFunction> function) {
   // If the function is not compiled ignore the lazy
   // recompilation. This can happen if the debugger is activated and
   // the function is returned to the not compiled state.
-  if (!function->shared()->is_compiled()) {
-    function->ReplaceCode(function->shared()->code());
-    return function->code();
-  }
+  if (!function->shared()->is_compiled()) return false;

// If the function is not optimizable or debugger is active continue using the
   // code from the full compiler.
   if (!FLAG_crankshaft ||
-      !function->shared()->code()->optimizable() ||
+      function->shared()->optimization_disabled() ||
       isolate->DebuggerHasBreakPoints()) {
     if (FLAG_trace_opt) {
       PrintF("[failed to optimize ");
       function->PrintName();
       PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
-          function->shared()->code()->optimizable() ? "T" : "F",
+          function->shared()->optimization_disabled() ? "F" : "T",
           isolate->DebuggerHasBreakPoints() ? "T" : "F");
     }
+    return false;
+  }
+  return true;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  Handle<JSFunction> function = args.at<JSFunction>(0);
+
+  if (!AllowOptimization(isolate, function)) {
     function->ReplaceCode(function->shared()->code());
     return function->code();
   }
@@ -7728,8 +7733,14 @@

 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParallelRecompile) {
   HandleScope handle_scope(isolate);
+  Handle<JSFunction> function = args.at<JSFunction>(0);
+  if (!AllowOptimization(isolate, function)) {
+    function->ReplaceCode(function->shared()->code());
+    return function->code();
+  }
+  function->shared()->code()->set_profiler_ticks(0);
   ASSERT(FLAG_parallel_recompilation);
-  Compiler::RecompileParallel(args.at<JSFunction>(0));
+  Compiler::RecompileParallel(function);
   return isolate->heap()->undefined_value();
 }

@@ -7913,10 +7924,13 @@
   if (args.length() == 2 &&
       unoptimized->kind() == Code::FUNCTION) {
     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
-    CHECK(type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr")));
-    isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
-    unoptimized->set_allow_osr_at_loop_nesting_level(
-        Code::kMaxLoopNestingMarker);
+    if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
+      isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
+      unoptimized->set_allow_osr_at_loop_nesting_level(
+          Code::kMaxLoopNestingMarker);
+    } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("parallel"))) {
+      function->MarkForParallelRecompilation();
+    }
   }

   return isolate->heap()->undefined_value();
=======================================
--- /branches/bleeding_edge/src/smart-pointers.h        Tue Dec 18 08:25:45 2012
+++ /branches/bleeding_edge/src/smart-pointers.h        Tue Mar  5 08:22:08 2013
@@ -129,11 +129,12 @@

 template<typename T>
 struct ObjectDeallocator {
-  static void Delete(T* array) {
-    Malloced::Delete(array);
+  static void Delete(T* object) {
+    delete object;
   }
 };

+
 template<typename T>
 class SmartPointer: public SmartPointerBase<ObjectDeallocator<T>, T> {
  public:

--
--
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.


Reply via email to