Commit 71ba8c5f authored by yangguo@chromium.org's avatar yangguo@chromium.org

Retire concurrent recompilation delay for non-stress testing.

Instead, we block concurrent recompilation until unblocked. This makes
affected tests more predictable and run shorter.

R=jkummerow@chromium.org
BUG=

Review URL: https://codereview.chromium.org/26758003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17199 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2d0d210e
...@@ -328,6 +328,8 @@ DEFINE_int(concurrent_recompilation_queue_length, 8, ...@@ -328,6 +328,8 @@ DEFINE_int(concurrent_recompilation_queue_length, 8,
"the length of the concurrent compilation queue") "the length of the concurrent compilation queue")
DEFINE_int(concurrent_recompilation_delay, 0, DEFINE_int(concurrent_recompilation_delay, 0,
"artificial compilation delay in ms") "artificial compilation delay in ms")
DEFINE_bool(block_concurrent_recompilation, false,
"block queued jobs until released")
DEFINE_bool(concurrent_osr, false, DEFINE_bool(concurrent_osr, false,
"concurrent on-stack replacement") "concurrent on-stack replacement")
DEFINE_implication(concurrent_osr, concurrent_recompilation) DEFINE_implication(concurrent_osr, concurrent_recompilation)
......
...@@ -168,6 +168,7 @@ void OptimizingCompilerThread::FlushOsrBuffer(bool restore_function_code) { ...@@ -168,6 +168,7 @@ void OptimizingCompilerThread::FlushOsrBuffer(bool restore_function_code) {
void OptimizingCompilerThread::Flush() { void OptimizingCompilerThread::Flush() {
ASSERT(!IsOptimizerThread()); ASSERT(!IsOptimizerThread());
Release_Store(&stop_thread_, static_cast<AtomicWord>(FLUSH)); Release_Store(&stop_thread_, static_cast<AtomicWord>(FLUSH));
if (FLAG_block_concurrent_recompilation) Unblock();
input_queue_semaphore_.Signal(); input_queue_semaphore_.Signal();
stop_semaphore_.Wait(); stop_semaphore_.Wait();
FlushOutputQueue(true); FlushOutputQueue(true);
...@@ -181,6 +182,7 @@ void OptimizingCompilerThread::Flush() { ...@@ -181,6 +182,7 @@ void OptimizingCompilerThread::Flush() {
void OptimizingCompilerThread::Stop() { void OptimizingCompilerThread::Stop() {
ASSERT(!IsOptimizerThread()); ASSERT(!IsOptimizerThread());
Release_Store(&stop_thread_, static_cast<AtomicWord>(STOP)); Release_Store(&stop_thread_, static_cast<AtomicWord>(STOP));
if (FLAG_block_concurrent_recompilation) Unblock();
input_queue_semaphore_.Signal(); input_queue_semaphore_.Signal();
stop_semaphore_.Wait(); stop_semaphore_.Wait();
...@@ -252,7 +254,20 @@ void OptimizingCompilerThread::QueueForOptimization(RecompileJob* job) { ...@@ -252,7 +254,20 @@ void OptimizingCompilerThread::QueueForOptimization(RecompileJob* job) {
info->closure()->MarkInRecompileQueue(); info->closure()->MarkInRecompileQueue();
} }
input_queue_.Enqueue(job); input_queue_.Enqueue(job);
input_queue_semaphore_.Signal(); if (FLAG_block_concurrent_recompilation) {
blocked_jobs_++;
} else {
input_queue_semaphore_.Signal();
}
}
void OptimizingCompilerThread::Unblock() {
ASSERT(!IsOptimizerThread());
while (blocked_jobs_ > 0) {
input_queue_semaphore_.Signal();
blocked_jobs_--;
}
} }
......
...@@ -55,7 +55,8 @@ class OptimizingCompilerThread : public Thread { ...@@ -55,7 +55,8 @@ class OptimizingCompilerThread : public Thread {
input_queue_semaphore_(0), input_queue_semaphore_(0),
osr_cursor_(0), osr_cursor_(0),
osr_hits_(0), osr_hits_(0),
osr_attempts_(0) { osr_attempts_(0),
blocked_jobs_(0) {
NoBarrier_Store(&stop_thread_, static_cast<AtomicWord>(CONTINUE)); NoBarrier_Store(&stop_thread_, static_cast<AtomicWord>(CONTINUE));
NoBarrier_Store(&queue_length_, static_cast<AtomicWord>(0)); NoBarrier_Store(&queue_length_, static_cast<AtomicWord>(0));
if (FLAG_concurrent_osr) { if (FLAG_concurrent_osr) {
...@@ -73,6 +74,7 @@ class OptimizingCompilerThread : public Thread { ...@@ -73,6 +74,7 @@ class OptimizingCompilerThread : public Thread {
void Stop(); void Stop();
void Flush(); void Flush();
void QueueForOptimization(RecompileJob* optimizing_compiler); void QueueForOptimization(RecompileJob* optimizing_compiler);
void Unblock();
void InstallOptimizedFunctions(); void InstallOptimizedFunctions();
RecompileJob* FindReadyOSRCandidate(Handle<JSFunction> function, RecompileJob* FindReadyOSRCandidate(Handle<JSFunction> function,
uint32_t osr_pc_offset); uint32_t osr_pc_offset);
...@@ -141,6 +143,8 @@ class OptimizingCompilerThread : public Thread { ...@@ -141,6 +143,8 @@ class OptimizingCompilerThread : public Thread {
int osr_hits_; int osr_hits_;
int osr_attempts_; int osr_attempts_;
int blocked_jobs_;
}; };
} } // namespace v8::internal } } // namespace v8::internal
......
...@@ -8579,6 +8579,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) { ...@@ -8579,6 +8579,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
} }
RUNTIME_FUNCTION(MaybeObject*, Runtime_UnblockConcurrentRecompilation) {
RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
isolate->optimizing_compiler_thread()->Unblock();
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) { RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) {
HandleScope scope(isolate); HandleScope scope(isolate);
ASSERT(args.length() == 1); ASSERT(args.length() == 1);
......
...@@ -99,6 +99,7 @@ namespace internal { ...@@ -99,6 +99,7 @@ namespace internal {
F(NeverOptimizeFunction, 1, 1) \ F(NeverOptimizeFunction, 1, 1) \
F(GetOptimizationStatus, -1, 1) \ F(GetOptimizationStatus, -1, 1) \
F(GetOptimizationCount, 1, 1) \ F(GetOptimizationCount, 1, 1) \
F(UnblockConcurrentRecompilation, 0, 1) \
F(CompileForOnStackReplacement, 2, 1) \ F(CompileForOnStackReplacement, 2, 1) \
F(SetAllocationTimeout, 2, 1) \ F(SetAllocationTimeout, 2, 1) \
F(AllocateInNewSpace, 1, 1) \ F(AllocateInNewSpace, 1, 1) \
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --track-fields --track-double-fields --allow-natives-syntax // Flags: --track-fields --track-double-fields --allow-natives-syntax
// Flags: --concurrent-recompilation --concurrent-recompilation-delay=100 // Flags: --concurrent-recompilation --block-concurrent-recompilation
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
...@@ -49,9 +49,13 @@ add_field(new_object()); ...@@ -49,9 +49,13 @@ add_field(new_object());
%OptimizeFunctionOnNextCall(add_field, "concurrent"); %OptimizeFunctionOnNextCall(add_field, "concurrent");
var o = new_object(); var o = new_object();
// Trigger optimization in the background thread. // Kick off recompilation.
add_field(o); add_field(o);
// Invalidate transition map while optimization is underway. // Invalidate transition map after compile graph has been created.
o.c = 2.2; o.c = 2.2;
// In the mean time, concurrent recompiling is still blocked.
assertUnoptimized(add_field, "no sync");
// Let concurrent recompilation proceed.
%UnblockConcurrentRecompilation();
// Sync with background thread to conclude optimization that bailed out. // Sync with background thread to conclude optimization that bailed out.
assertUnoptimized(add_field, "sync"); assertUnoptimized(add_field, "sync");
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax
// Flags: --concurrent-recompilation --concurrent-recompilation-delay=50 // Flags: --concurrent-recompilation --block-concurrent-recompilation
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
...@@ -43,12 +43,14 @@ assertEquals(1, f(o)); ...@@ -43,12 +43,14 @@ assertEquals(1, f(o));
// Mark for concurrent optimization. // Mark for concurrent optimization.
%OptimizeFunctionOnNextCall(f, "concurrent"); %OptimizeFunctionOnNextCall(f, "concurrent");
// Trigger optimization in the background thread. // Kick off recompilation.
assertEquals(1, f(o)); assertEquals(1, f(o));
// While concurrent recompilation is running, optimization not yet done. // Change the prototype chain after compile graph has been created.
assertUnoptimized(f, "no sync");
// Change the prototype chain during optimization to trigger map invalidation.
o.__proto__.__proto__ = { bar: function() { return 2; } }; o.__proto__.__proto__ = { bar: function() { return 2; } };
// At this point, concurrent recompilation thread has not yet done its job.
assertUnoptimized(f, "no sync");
// Let the background thread proceed.
%UnblockConcurrentRecompilation();
// Optimization eventually bails out due to map dependency. // Optimization eventually bails out due to map dependency.
assertUnoptimized(f, "sync"); assertUnoptimized(f, "sync");
assertEquals(2, f(o)); assertEquals(2, f(o));
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc // Flags: --allow-natives-syntax --expose-gc
// Flags: --concurrent-recompilation --concurrent-recompilation-delay=50 // Flags: --concurrent-recompilation --block-concurrent-recompilation
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
...@@ -55,10 +55,13 @@ assertUnoptimized(g); ...@@ -55,10 +55,13 @@ assertUnoptimized(g);
%OptimizeFunctionOnNextCall(f, "concurrent"); %OptimizeFunctionOnNextCall(f, "concurrent");
%OptimizeFunctionOnNextCall(g, "concurrent"); %OptimizeFunctionOnNextCall(g, "concurrent");
f(g(2)); // Trigger optimization. f(g(2)); // Kick off recompilation.
assertUnoptimized(f, "no sync"); // Not yet optimized while background thread assertUnoptimized(f, "no sync"); // Not yet optimized since recompilation
assertUnoptimized(g, "no sync"); // is running. assertUnoptimized(g, "no sync"); // is still blocked.
// Let concurrent recompilation proceed.
%UnblockConcurrentRecompilation();
assertOptimized(f, "sync"); // Optimized once we sync with the assertOptimized(f, "sync"); // Optimized once we sync with the
assertOptimized(g, "sync"); // background thread. assertOptimized(g, "sync"); // background thread.
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax
// Flags: --concurrent-recompilation --concurrent-recompilation-delay=100 // Flags: --concurrent-recompilation --block-concurrent-recompilation
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
...@@ -43,12 +43,15 @@ assertEquals(0.5, f1(arr, 0)); ...@@ -43,12 +43,15 @@ assertEquals(0.5, f1(arr, 0));
// Optimized code of f1 depends on initial object and array maps. // Optimized code of f1 depends on initial object and array maps.
%OptimizeFunctionOnNextCall(f1, "concurrent"); %OptimizeFunctionOnNextCall(f1, "concurrent");
// Trigger optimization in the background thread // Kick off recompilation;
assertEquals(0.5, f1(arr, 0)); assertEquals(0.5, f1(arr, 0));
Object.prototype[1] = 1.5; // Invalidate current initial object map. // Invalidate current initial object map after compile graph has been created.
Object.prototype[1] = 1.5;
assertEquals(2, f1(arr, 1)); assertEquals(2, f1(arr, 1));
// Not yet optimized while background thread is running. // Not yet optimized since concurrent recompilation is blocked.
assertUnoptimized(f1, "no sync"); assertUnoptimized(f1, "no sync");
// Let concurrent recompilation proceed.
%UnblockConcurrentRecompilation();
// Sync with background thread to conclude optimization, which bails out // Sync with background thread to conclude optimization, which bails out
// due to map dependency. // due to map dependency.
assertUnoptimized(f1, "sync"); assertUnoptimized(f1, "sync");
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
// Flags: --fold-constants --nodead-code-elimination // Flags: --fold-constants --nodead-code-elimination
// Flags: --expose-gc --allow-natives-syntax // Flags: --expose-gc --allow-natives-syntax
// Flags: --concurrent-recompilation --concurrent-recompilation-delay=600 // Flags: --concurrent-recompilation --block-concurrent-recompilation
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
...@@ -39,12 +39,14 @@ function test(fun) { ...@@ -39,12 +39,14 @@ function test(fun) {
fun(); fun();
// Mark for concurrent optimization. // Mark for concurrent optimization.
%OptimizeFunctionOnNextCall(fun, "concurrent"); %OptimizeFunctionOnNextCall(fun, "concurrent");
//Trigger optimization in the background. // Kick off recompilation.
fun(); fun();
//Tenure cons string. // Tenure cons string after compile graph has been created.
gc(); gc();
// In the mean time, concurrent recompiling is not complete yet. // In the mean time, concurrent recompiling is still blocked.
assertUnoptimized(fun, "no sync"); assertUnoptimized(fun, "no sync");
// Let concurrent recompilation proceed.
%UnblockConcurrentRecompilation();
// Concurrent recompilation eventually finishes, embeds tenured cons string. // Concurrent recompilation eventually finishes, embeds tenured cons string.
assertOptimized(fun, "sync"); assertOptimized(fun, "sync");
// Visit embedded cons string during mark compact. // Visit embedded cons string during mark compact.
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --allow-natives-syntax // Flags: --expose-debug-as debug --allow-natives-syntax
// Flags: --concurrent-recompilation --concurrent-recompilation-delay=100 // Flags: --concurrent-recompilation --block-concurrent-recompilation
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
...@@ -60,8 +60,14 @@ f(); ...@@ -60,8 +60,14 @@ f();
%OptimizeFunctionOnNextCall(f, "concurrent"); // Mark with builtin. %OptimizeFunctionOnNextCall(f, "concurrent"); // Mark with builtin.
f(); // Kick off concurrent recompilation. f(); // Kick off concurrent recompilation.
// After compile graph has been created...
Debug.setListener(listener); // Activate debugger. Debug.setListener(listener); // Activate debugger.
Debug.setBreakPoint(f, 2, 0); // Force deopt. Debug.setBreakPoint(f, 2, 0); // Force deopt.
// At this point, concurrent recompilation is still being blocked.
assertUnoptimized(f, "no sync");
// Let concurrent recompilation proceed.
%UnblockConcurrentRecompilation();
// Sync with optimization thread. But no optimized code is installed. // Sync with optimization thread. But no optimized code is installed.
assertUnoptimized(f, "sync"); assertUnoptimized(f, "sync");
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --allow-natives-syntax // Flags: --expose-debug-as debug --allow-natives-syntax
// Flags: --concurrent-recompilation-delay=300 // Flags: --block-concurrent-recompilation
if (!%IsConcurrentRecompilationSupported()) { if (!%IsConcurrentRecompilationSupported()) {
print("Concurrent recompilation is disabled. Skipping this test."); print("Concurrent recompilation is disabled. Skipping this test.");
...@@ -46,17 +46,22 @@ function bar() { ...@@ -46,17 +46,22 @@ function bar() {
} }
foo(); foo();
// Mark and trigger concurrent optimization. // Mark and kick off recompilation.
%OptimizeFunctionOnNextCall(foo, "concurrent"); %OptimizeFunctionOnNextCall(foo, "concurrent");
foo(); foo();
// Set break points on an unrelated function. This clears both optimized // Set break points on an unrelated function. This clears both optimized
// and (shared) unoptimized code on foo, and sets both to lazy-compile builtin. // and (shared) unoptimized code on foo, and sets both to lazy-compile builtin.
// Clear the break point immediately after to deactivate the debugger. // Clear the break point immediately after to deactivate the debugger.
// Do all of this after compile graph has been created.
Debug.setBreakPoint(bar, 0, 0); Debug.setBreakPoint(bar, 0, 0);
Debug.clearAllBreakPoints(); Debug.clearAllBreakPoints();
// At this point, concurrent recompilation is still blocked.
assertUnoptimized(foo, "no sync");
// Let concurrent recompilation proceed.
%UnblockConcurrentRecompilation();
// Install optimized code when concurrent optimization finishes. // Install optimized code when concurrent optimization finishes.
// This needs to be able to deal with shared code being a builtin. // This needs to be able to deal with shared code being a builtin.
assertUnoptimized(foo, "sync"); assertUnoptimized(foo, "sync");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment