Commit 9f902b74 authored by Fanchen Kong's avatar Fanchen Kong Committed by V8 LUCI CQ

[turbofan] Making OSR concurrent

... to reduce compilation overhead on the main thread for OSR

Bug: v8:12161
Change-Id: I54ca5fa6201405daf92dac9cf51d5de4b46577b3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3369361Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Fanchen Kong <fanchen.kong@intel.com>
Cr-Commit-Position: refs/heads/main@{#79188}
parent 6573bce1
...@@ -163,11 +163,21 @@ class CompilerTracer : public AllStatic { ...@@ -163,11 +163,21 @@ class CompilerTracer : public AllStatic {
PrintF(scope.file(), "]\n"); PrintF(scope.file(), "]\n");
} }
static void TraceStartConcurrentOSRJob(Isolate* isolate,
Handle<JSFunction> function,
OptimizedCompilationInfo* info) {
if (!FLAG_trace_osr) return;
CodeTracer::Scope scope(isolate->GetCodeTracer());
PrintTracePrefix(scope, "OSR - Concurrent compiling: ", info);
PrintTraceSuffix(scope);
}
private: private:
static void PrintTracePrefix(const CodeTracer::Scope& scope, static void PrintTracePrefix(const CodeTracer::Scope& scope,
const char* header, const char* header,
OptimizedCompilationInfo* info) { OptimizedCompilationInfo* info) {
PrintTracePrefix(scope, header, info->closure(), info->code_kind()); PrintTracePrefix(scope, header, info->closure(), info->code_kind());
PrintF(scope.file(), " osr target offset %d", info->osr_offset().ToInt());
} }
static void PrintTracePrefix(const CodeTracer::Scope& scope, static void PrintTracePrefix(const CodeTracer::Scope& scope,
...@@ -990,7 +1000,12 @@ bool GetOptimizedCodeLater(std::unique_ptr<OptimizedCompilationJob> job, ...@@ -990,7 +1000,12 @@ bool GetOptimizedCodeLater(std::unique_ptr<OptimizedCompilationJob> job,
} }
if (CodeKindIsStoredInOptimizedCodeCache(code_kind)) { if (CodeKindIsStoredInOptimizedCodeCache(code_kind)) {
function->SetOptimizationMarker(OptimizationMarker::kInOptimizationQueue); if (compilation_info->is_osr()) {
DCHECK(function->has_feedback_vector());
function->shared().set_osr_is_in_optimization_queue(true);
} else {
function->SetOptimizationMarker(OptimizationMarker::kInOptimizationQueue);
}
} }
// Note: Usually the active tier is expected to be Ignition at this point (in // Note: Usually the active tier is expected to be Ignition at this point (in
...@@ -1026,14 +1041,18 @@ MaybeHandle<CodeT> GetOptimizedCode( ...@@ -1026,14 +1041,18 @@ MaybeHandle<CodeT> GetOptimizedCode(
CodeKind code_kind, BytecodeOffset osr_offset = BytecodeOffset::None(), CodeKind code_kind, BytecodeOffset osr_offset = BytecodeOffset::None(),
JavaScriptFrame* osr_frame = nullptr, JavaScriptFrame* osr_frame = nullptr,
GetOptimizedCodeResultHandling result_handling = GetOptimizedCodeResultHandling result_handling =
GetOptimizedCodeResultHandling::kDefault) { GetOptimizedCodeResultHandling::kDefault,
int osr_depth = AbstractCode::kNoLoopNestingLevelValue) {
DCHECK(CodeKindIsOptimizedJSFunction(code_kind)); DCHECK(CodeKindIsOptimizedJSFunction(code_kind));
Handle<SharedFunctionInfo> shared(function->shared(), isolate); Handle<SharedFunctionInfo> shared(function->shared(), isolate);
// Make sure we clear the optimization marker on the function so that we // Make sure we clear the optimization marker on the function so that we
// don't try to re-optimize. // don't try to re-optimize.
if (function->HasOptimizationMarker()) function->ClearOptimizationMarker(); if (function->HasOptimizationMarker() &&
osr_offset == BytecodeOffset::None()) {
function->ClearOptimizationMarker();
}
if (shared->optimization_disabled() && if (shared->optimization_disabled() &&
shared->disabled_optimization_reason() == BailoutReason::kNeverOptimize) { shared->disabled_optimization_reason() == BailoutReason::kNeverOptimize) {
...@@ -1057,7 +1076,9 @@ MaybeHandle<CodeT> GetOptimizedCode( ...@@ -1057,7 +1076,9 @@ MaybeHandle<CodeT> GetOptimizedCode(
} }
// Check the optimized code cache (stored on the SharedFunctionInfo). // Check the optimized code cache (stored on the SharedFunctionInfo).
if (CodeKindIsStoredInOptimizedCodeCache(code_kind)) { // For OSR, this is handled at GetOptimizedCodeForOSR.
if (CodeKindIsStoredInOptimizedCodeCache(code_kind) &&
osr_offset == BytecodeOffset::None()) {
Handle<CodeT> cached_code; Handle<CodeT> cached_code;
if (GetCodeFromOptimizedCodeCache(function, osr_offset, code_kind) if (GetCodeFromOptimizedCodeCache(function, osr_offset, code_kind)
.ToHandle(&cached_code)) { .ToHandle(&cached_code)) {
...@@ -1069,7 +1090,9 @@ MaybeHandle<CodeT> GetOptimizedCode( ...@@ -1069,7 +1090,9 @@ MaybeHandle<CodeT> GetOptimizedCode(
// Reset profiler ticks, function is no longer considered hot. // Reset profiler ticks, function is no longer considered hot.
DCHECK(shared->is_compiled()); DCHECK(shared->is_compiled());
function->feedback_vector().set_profiler_ticks(0); if (osr_offset == BytecodeOffset::None()) {
function->feedback_vector().set_profiler_ticks(0);
}
VMState<COMPILER> state(isolate); VMState<COMPILER> state(isolate);
TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate);
...@@ -1095,6 +1118,16 @@ MaybeHandle<CodeT> GetOptimizedCode( ...@@ -1095,6 +1118,16 @@ MaybeHandle<CodeT> GetOptimizedCode(
if (mode == ConcurrencyMode::kConcurrent) { if (mode == ConcurrencyMode::kConcurrent) {
if (GetOptimizedCodeLater(std::move(job), isolate, compilation_info, if (GetOptimizedCodeLater(std::move(job), isolate, compilation_info,
code_kind, function)) { code_kind, function)) {
if (osr_offset != BytecodeOffset::None()) {
DCHECK(isolate->concurrent_osr_enabled());
compilation_info->set_osr_depth(osr_depth);
DCHECK(shared->osr_is_in_optimization_queue());
CompilerTracer::TraceStartConcurrentOSRJob(isolate, function,
compilation_info);
// Return empty handle when execution continues and concurrent
// optimization job for OSR has been started (but not finished).
return Handle<CodeT>();
}
return ContinuationForConcurrentOptimization(isolate, function); return ContinuationForConcurrentOptimization(isolate, function);
} }
} else { } else {
...@@ -3204,13 +3237,40 @@ template Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( ...@@ -3204,13 +3237,40 @@ template Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
FunctionLiteral* literal, Handle<Script> script, LocalIsolate* isolate); FunctionLiteral* literal, Handle<Script> script, LocalIsolate* isolate);
// static // static
MaybeHandle<CodeT> Compiler::GetOptimizedCodeForOSR( MaybeHandle<CodeT> Compiler::GetOptimizedCodeForOSR(Isolate* isolate,
Isolate* isolate, Handle<JSFunction> function, BytecodeOffset osr_offset, Handle<JSFunction> function,
JavaScriptFrame* osr_frame) { BytecodeOffset osr_offset,
JavaScriptFrame* osr_frame,
int osr_depth) {
DCHECK(!osr_offset.IsNone()); DCHECK(!osr_offset.IsNone());
DCHECK_NOT_NULL(osr_frame); DCHECK_NOT_NULL(osr_frame);
return GetOptimizedCode(isolate, function, ConcurrencyMode::kNotConcurrent, DCHECK(0 <= osr_depth && osr_depth <= AbstractCode::kMaxLoopNestingMarker);
CodeKindForOSR(), osr_offset, osr_frame);
CodeKind code_kind = CodeKindForOSR();
// Check the optimized code cache.
if (CodeKindIsStoredInOptimizedCodeCache(code_kind)) {
Handle<CodeT> cached_code;
if (GetCodeFromOptimizedCodeCache(function, osr_offset, code_kind)
.ToHandle(&cached_code)) {
CompilerTracer::TraceOptimizedCodeCacheHit(isolate, function, osr_offset,
code_kind);
return cached_code;
}
}
if (isolate->concurrent_osr_enabled() &&
function->shared().osr_is_in_optimization_queue()) {
return {};
}
return GetOptimizedCode(
isolate, function,
isolate->concurrent_osr_enabled() && !isolate->bootstrapper()->IsActive()
? ConcurrencyMode::kConcurrent
: ConcurrencyMode::kNotConcurrent,
code_kind, osr_offset, osr_frame,
GetOptimizedCodeResultHandling::kDefault, osr_depth);
} }
// static // static
...@@ -3229,7 +3289,7 @@ bool Compiler::FinalizeOptimizedCompilationJob(OptimizedCompilationJob* job, ...@@ -3229,7 +3289,7 @@ bool Compiler::FinalizeOptimizedCompilationJob(OptimizedCompilationJob* job,
Handle<SharedFunctionInfo> shared = compilation_info->shared_info(); Handle<SharedFunctionInfo> shared = compilation_info->shared_info();
const bool use_result = !compilation_info->discard_result_for_testing(); const bool use_result = !compilation_info->discard_result_for_testing();
if (V8_LIKELY(use_result)) { if (V8_LIKELY(use_result) && !compilation_info->is_osr()) {
// Reset profiler ticks, function is no longer considered hot. // Reset profiler ticks, function is no longer considered hot.
compilation_info->closure()->feedback_vector().set_profiler_ticks(0); compilation_info->closure()->feedback_vector().set_profiler_ticks(0);
} }
...@@ -3252,9 +3312,21 @@ bool Compiler::FinalizeOptimizedCompilationJob(OptimizedCompilationJob* job, ...@@ -3252,9 +3312,21 @@ bool Compiler::FinalizeOptimizedCompilationJob(OptimizedCompilationJob* job,
if (V8_LIKELY(use_result)) { if (V8_LIKELY(use_result)) {
InsertCodeIntoOptimizedCodeCache(compilation_info); InsertCodeIntoOptimizedCodeCache(compilation_info);
CompilerTracer::TraceCompletedJob(isolate, compilation_info); CompilerTracer::TraceCompletedJob(isolate, compilation_info);
compilation_info->closure()->set_code(*compilation_info->code(), if (!compilation_info->is_osr()) {
kReleaseStore); compilation_info->closure()->set_code(*compilation_info->code(),
kReleaseStore);
} else {
DCHECK(shared->osr_is_in_optimization_queue());
shared->set_osr_is_in_optimization_queue(false);
// Store new loop nesting level to trigger OSR and use the optimized
// code from OSROptimizedCodeCache during the later execution if
// bytecode offsets match.
int osr_depth = compilation_info->osr_depth();
shared->GetBytecodeArray(isolate).set_osr_loop_nesting_level(
std::min({osr_depth + 1, AbstractCode::kMaxLoopNestingMarker}));
}
} }
return CompilationJob::SUCCEEDED; return CompilationJob::SUCCEEDED;
} }
} }
...@@ -3268,6 +3340,9 @@ bool Compiler::FinalizeOptimizedCompilationJob(OptimizedCompilationJob* job, ...@@ -3268,6 +3340,9 @@ bool Compiler::FinalizeOptimizedCompilationJob(OptimizedCompilationJob* job,
compilation_info->closure()->ClearOptimizationMarker(); compilation_info->closure()->ClearOptimizationMarker();
} }
} }
if (compilation_info->is_osr() && shared->osr_is_in_optimization_queue()) {
shared->set_osr_is_in_optimization_queue(false);
}
return CompilationJob::FAILED; return CompilationJob::FAILED;
} }
......
...@@ -236,7 +236,7 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic { ...@@ -236,7 +236,7 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
// Generate and return optimized code for OSR, or empty handle on failure. // Generate and return optimized code for OSR, or empty handle on failure.
V8_WARN_UNUSED_RESULT static MaybeHandle<CodeT> GetOptimizedCodeForOSR( V8_WARN_UNUSED_RESULT static MaybeHandle<CodeT> GetOptimizedCodeForOSR(
Isolate* isolate, Handle<JSFunction> function, BytecodeOffset osr_offset, Isolate* isolate, Handle<JSFunction> function, BytecodeOffset osr_offset,
JavaScriptFrame* osr_frame); JavaScriptFrame* osr_frame, int osr_depth);
}; };
// A base class for compilation jobs intended to run concurrent to the main // A base class for compilation jobs intended to run concurrent to the main
......
...@@ -241,6 +241,10 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final { ...@@ -241,6 +241,10 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final {
return std::move(canonical_handles_); return std::move(canonical_handles_);
} }
void set_osr_depth(int n) { osr_depth_ = n; }
int osr_depth() const { return osr_depth_; }
private: private:
void ConfigureFlags(); void ConfigureFlags();
...@@ -312,6 +316,8 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final { ...@@ -312,6 +316,8 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final {
// handles above. The only difference is that is created in the // handles above. The only difference is that is created in the
// CanonicalHandleScope(i.e step 1) is different). // CanonicalHandleScope(i.e step 1) is different).
std::unique_ptr<CanonicalHandlesMap> canonical_handles_; std::unique_ptr<CanonicalHandlesMap> canonical_handles_;
int osr_depth_ = AbstractCode::kNoLoopNestingLevelValue;
}; };
} // namespace internal } // namespace internal
......
...@@ -32,6 +32,9 @@ void DisposeCompilationJob(OptimizedCompilationJob* job, ...@@ -32,6 +32,9 @@ void DisposeCompilationJob(OptimizedCompilationJob* job,
if (function->IsInOptimizationQueue()) { if (function->IsInOptimizationQueue()) {
function->ClearOptimizationMarker(); function->ClearOptimizationMarker();
} }
if (job->compilation_info()->is_osr()) {
function->shared().set_osr_is_in_optimization_queue(false);
}
} }
delete job; delete job;
} }
...@@ -205,7 +208,7 @@ void OptimizingCompileDispatcher::InstallOptimizedFunctions() { ...@@ -205,7 +208,7 @@ void OptimizingCompileDispatcher::InstallOptimizedFunctions() {
} }
OptimizedCompilationInfo* info = job->compilation_info(); OptimizedCompilationInfo* info = job->compilation_info();
Handle<JSFunction> function(*info->closure(), isolate_); Handle<JSFunction> function(*info->closure(), isolate_);
if (function->HasAvailableCodeKind(info->code_kind())) { if (function->HasAvailableCodeKind(info->code_kind()) && !info->is_osr()) {
if (FLAG_trace_concurrent_recompilation) { if (FLAG_trace_concurrent_recompilation) {
PrintF(" ** Aborting compilation for "); PrintF(" ** Aborting compilation for ");
function->ShortPrint(); function->ShortPrint();
......
...@@ -453,6 +453,11 @@ void Deoptimizer::DeoptimizeFunction(JSFunction function, Code code) { ...@@ -453,6 +453,11 @@ void Deoptimizer::DeoptimizeFunction(JSFunction function, Code code) {
// this call from here. // this call from here.
OSROptimizedCodeCache::Compact( OSROptimizedCodeCache::Compact(
Handle<NativeContext>(function.context().native_context(), isolate)); Handle<NativeContext>(function.context().native_context(), isolate));
// Background compilation for OSR arm back edges at compilation finalization
// stage regardless of the active execution state (unoptimized/optimized).
// Reset osr_loop_nesting_level to avoid unwanted OSR from unoptimized frame
// after deoptimization.
function.shared().GetBytecodeArray(isolate).set_osr_loop_nesting_level(0);
} }
} }
......
...@@ -1468,13 +1468,17 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { ...@@ -1468,13 +1468,17 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
return baseline_batch_compiler_; return baseline_batch_compiler_;
} }
bool concurrent_recompilation_enabled() { bool concurrent_recompilation_enabled() const {
// Thread is only available with flag enabled. // Thread is only available with flag enabled.
DCHECK(optimizing_compile_dispatcher_ == nullptr || DCHECK(optimizing_compile_dispatcher_ == nullptr ||
FLAG_concurrent_recompilation); FLAG_concurrent_recompilation);
return optimizing_compile_dispatcher_ != nullptr; return optimizing_compile_dispatcher_ != nullptr;
} }
bool concurrent_osr_enabled() const {
return concurrent_recompilation_enabled() && FLAG_concurrent_osr;
}
OptimizingCompileDispatcher* optimizing_compile_dispatcher() { OptimizingCompileDispatcher* optimizing_compile_dispatcher() {
DCHECK_NOT_NULL(optimizing_compile_dispatcher_); DCHECK_NOT_NULL(optimizing_compile_dispatcher_);
return optimizing_compile_dispatcher_; return optimizing_compile_dispatcher_;
......
...@@ -123,7 +123,6 @@ void TieringManager::MaybeOptimizeFrame(JSFunction function, ...@@ -123,7 +123,6 @@ void TieringManager::MaybeOptimizeFrame(JSFunction function,
CodeKind code_kind) { CodeKind code_kind) {
if (function.IsInOptimizationQueue()) { if (function.IsInOptimizationQueue()) {
TraceInOptimizationQueue(function); TraceInOptimizationQueue(function);
return;
} }
if (FLAG_testing_d8_test_runner && if (FLAG_testing_d8_test_runner &&
...@@ -155,6 +154,7 @@ void TieringManager::MaybeOptimizeFrame(JSFunction function, ...@@ -155,6 +154,7 @@ void TieringManager::MaybeOptimizeFrame(JSFunction function,
} }
bool TieringManager::MaybeOSR(JSFunction function, UnoptimizedFrame* frame) { bool TieringManager::MaybeOSR(JSFunction function, UnoptimizedFrame* frame) {
if (function.shared().osr_is_in_optimization_queue()) return false;
int ticks = function.feedback_vector().profiler_ticks(); int ticks = function.feedback_vector().profiler_ticks();
if (function.IsMarkedForOptimization() || if (function.IsMarkedForOptimization() ||
function.IsMarkedForConcurrentOptimization() || function.IsMarkedForConcurrentOptimization() ||
...@@ -181,9 +181,6 @@ bool ShouldOptimizeAsSmallFunction(int bytecode_size, bool any_ic_changed) { ...@@ -181,9 +181,6 @@ bool ShouldOptimizeAsSmallFunction(int bytecode_size, bool any_ic_changed) {
OptimizationReason TieringManager::ShouldOptimize(JSFunction function, OptimizationReason TieringManager::ShouldOptimize(JSFunction function,
BytecodeArray bytecode, BytecodeArray bytecode,
JavaScriptFrame* frame) { JavaScriptFrame* frame) {
if (function.ActiveTierIsTurbofan()) {
return OptimizationReason::kDoNotOptimize;
}
// If function's SFI has OSR cache, once enter loop range of OSR cache, set // If function's SFI has OSR cache, once enter loop range of OSR cache, set
// OSR loop nesting level for matching condition of OSR (loop_depth < // OSR loop nesting level for matching condition of OSR (loop_depth <
// osr_level), soon later OSR will be triggered when executing bytecode // osr_level), soon later OSR will be triggered when executing bytecode
...@@ -205,10 +202,18 @@ OptimizationReason TieringManager::ShouldOptimize(JSFunction function, ...@@ -205,10 +202,18 @@ OptimizationReason TieringManager::ShouldOptimize(JSFunction function,
current_offset >= jump_target_offset) { current_offset >= jump_target_offset) {
bytecode.set_osr_loop_nesting_level(iterator.GetImmediateOperand(1) + bytecode.set_osr_loop_nesting_level(iterator.GetImmediateOperand(1) +
1); 1);
return OptimizationReason::kHotAndStable; return function.ActiveTierIsTurbofan() ||
function.IsInOptimizationQueue()
? OptimizationReason::kDoNotOptimize
: OptimizationReason::kHotAndStable;
} }
} }
} }
if (function.ActiveTierIsTurbofan() || function.HasOptimizationMarker()) {
return OptimizationReason::kDoNotOptimize;
}
const int ticks = function.feedback_vector().profiler_ticks(); const int ticks = function.feedback_vector().profiler_ticks();
const int ticks_for_optimization = const int ticks_for_optimization =
FLAG_ticks_before_optimization + FLAG_ticks_before_optimization +
......
...@@ -553,6 +553,7 @@ DEFINE_BOOL(assert_types, false, ...@@ -553,6 +553,7 @@ DEFINE_BOOL(assert_types, false,
"generate runtime type assertions to test the typer") "generate runtime type assertions to test the typer")
// TODO(tebbi): Support allocating types from background thread. // TODO(tebbi): Support allocating types from background thread.
DEFINE_NEG_IMPLICATION(assert_types, concurrent_recompilation) DEFINE_NEG_IMPLICATION(assert_types, concurrent_recompilation)
DEFINE_NEG_IMPLICATION(assert_types, concurrent_osr)
DEFINE_BOOL(trace_compilation_dependencies, false, "trace code dependencies") DEFINE_BOOL(trace_compilation_dependencies, false, "trace code dependencies")
// Depend on --trace-deopt-verbose for reporting dependency invalidations. // Depend on --trace-deopt-verbose for reporting dependency invalidations.
...@@ -1544,6 +1545,8 @@ DEFINE_BOOL(always_opt, false, "always try to optimize functions") ...@@ -1544,6 +1545,8 @@ DEFINE_BOOL(always_opt, false, "always try to optimize functions")
DEFINE_IMPLICATION(always_opt, opt) DEFINE_IMPLICATION(always_opt, opt)
DEFINE_BOOL(always_osr, false, "always try to OSR functions") DEFINE_BOOL(always_osr, false, "always try to OSR functions")
DEFINE_BOOL(prepare_always_opt, false, "prepare for turning on always opt") DEFINE_BOOL(prepare_always_opt, false, "prepare for turning on always opt")
DEFINE_BOOL(concurrent_osr, true,
"compile turbofan optimized code for osr on background thread")
DEFINE_BOOL(trace_serializer, false, "print code serializer trace") DEFINE_BOOL(trace_serializer, false, "print code serializer trace")
#ifdef DEBUG #ifdef DEBUG
......
...@@ -814,6 +814,8 @@ class AbstractCode : public HeapObject { ...@@ -814,6 +814,8 @@ class AbstractCode : public HeapObject {
// nesting that is deeper than 5 levels into account. // nesting that is deeper than 5 levels into account.
static const int kMaxLoopNestingMarker = 6; static const int kMaxLoopNestingMarker = 6;
static const int kNoLoopNestingLevelValue = -1;
OBJECT_CONSTRUCTORS(AbstractCode, HeapObject); OBJECT_CONSTRUCTORS(AbstractCode, HeapObject);
private: private:
......
...@@ -261,6 +261,9 @@ BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags2, ...@@ -261,6 +261,9 @@ BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags2,
has_static_private_methods_or_accessors, has_static_private_methods_or_accessors,
SharedFunctionInfo::HasStaticPrivateMethodsOrAccessorsBit) SharedFunctionInfo::HasStaticPrivateMethodsOrAccessorsBit)
BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags2, osr_is_in_optimization_queue,
SharedFunctionInfo::OsrIsInOptimizationQueueBit)
BIT_FIELD_ACCESSORS(SharedFunctionInfo, relaxed_flags, syntax_kind, BIT_FIELD_ACCESSORS(SharedFunctionInfo, relaxed_flags, syntax_kind,
SharedFunctionInfo::FunctionSyntaxKindBits) SharedFunctionInfo::FunctionSyntaxKindBits)
......
...@@ -492,6 +492,8 @@ class SharedFunctionInfo ...@@ -492,6 +492,8 @@ class SharedFunctionInfo
// closest outer class scope. // closest outer class scope.
DECL_BOOLEAN_ACCESSORS(private_name_lookup_skips_outer_class) DECL_BOOLEAN_ACCESSORS(private_name_lookup_skips_outer_class)
DECL_BOOLEAN_ACCESSORS(osr_is_in_optimization_queue)
inline FunctionKind kind() const; inline FunctionKind kind() const;
// Defines the index in a native context of closure's map instantiated using // Defines the index in a native context of closure's map instantiated using
......
...@@ -44,6 +44,7 @@ bitfield struct SharedFunctionInfoFlags extends uint32 { ...@@ -44,6 +44,7 @@ bitfield struct SharedFunctionInfoFlags extends uint32 {
bitfield struct SharedFunctionInfoFlags2 extends uint8 { bitfield struct SharedFunctionInfoFlags2 extends uint8 {
class_scope_has_private_brand: bool: 1 bit; class_scope_has_private_brand: bool: 1 bit;
has_static_private_methods_or_accessors: bool: 1 bit; has_static_private_methods_or_accessors: bool: 1 bit;
osr_is_in_optimization_queue: bool: 1 bit;
} }
@generateBodyDescriptor @generateBodyDescriptor
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
#include "src/execution/v8threads.h" #include "src/execution/v8threads.h"
#include "src/execution/vm-state-inl.h" #include "src/execution/vm-state-inl.h"
#include "src/heap/parked-scope.h" #include "src/heap/parked-scope.h"
#include "src/interpreter/bytecode-array-iterator.h"
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/interpreter.h"
#include "src/objects/js-array-buffer-inl.h" #include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h" #include "src/objects/js-array-inl.h"
#include "src/objects/shared-function-info.h" #include "src/objects/shared-function-info.h"
...@@ -236,7 +239,7 @@ static bool IsSuitableForOnStackReplacement(Isolate* isolate, ...@@ -236,7 +239,7 @@ static bool IsSuitableForOnStackReplacement(Isolate* isolate,
namespace { namespace {
BytecodeOffset DetermineEntryAndDisarmOSRForUnoptimized( std::tuple<BytecodeOffset, int> DetermineEntryAndDisarmOSRForUnoptimized(
JavaScriptFrame* js_frame) { JavaScriptFrame* js_frame) {
UnoptimizedFrame* frame = reinterpret_cast<UnoptimizedFrame*>(js_frame); UnoptimizedFrame* frame = reinterpret_cast<UnoptimizedFrame*>(js_frame);
...@@ -257,9 +260,15 @@ BytecodeOffset DetermineEntryAndDisarmOSRForUnoptimized( ...@@ -257,9 +260,15 @@ BytecodeOffset DetermineEntryAndDisarmOSRForUnoptimized(
// Reset the OSR loop nesting depth to disarm back edges. // Reset the OSR loop nesting depth to disarm back edges.
bytecode->set_osr_loop_nesting_level(0); bytecode->set_osr_loop_nesting_level(0);
// Read depth of loop from bytecode array
interpreter::BytecodeArrayIterator bytecode_iterator(
bytecode, frame->GetBytecodeOffset());
int osr_depth = bytecode_iterator.GetImmediateOperand(1);
// Return a BytecodeOffset representing the bytecode offset of the back // Return a BytecodeOffset representing the bytecode offset of the back
// branch. // branch and an int which is the loop depth of the corresponding bytecode
return BytecodeOffset(frame->GetBytecodeOffset()); // offset.
return {BytecodeOffset(frame->GetBytecodeOffset()), osr_depth};
} }
} // namespace } // namespace
...@@ -278,7 +287,10 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { ...@@ -278,7 +287,10 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
// Determine the entry point for which this OSR request has been fired and // Determine the entry point for which this OSR request has been fired and
// also disarm all back edges in the calling code to stop new requests. // also disarm all back edges in the calling code to stop new requests.
BytecodeOffset osr_offset = DetermineEntryAndDisarmOSRForUnoptimized(frame); BytecodeOffset osr_offset = BytecodeOffset::None();
int osr_depth = AbstractCode::kNoLoopNestingLevelValue;
std::tie(osr_offset, osr_depth) =
DetermineEntryAndDisarmOSRForUnoptimized(frame);
DCHECK(!osr_offset.IsNone()); DCHECK(!osr_offset.IsNone());
MaybeHandle<CodeT> maybe_result; MaybeHandle<CodeT> maybe_result;
...@@ -290,8 +302,11 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { ...@@ -290,8 +302,11 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
function->PrintName(scope.file()); function->PrintName(scope.file());
PrintF(scope.file(), " at OSR bytecode offset %d]\n", osr_offset.ToInt()); PrintF(scope.file(), " at OSR bytecode offset %d]\n", osr_offset.ToInt());
} }
maybe_result =
Compiler::GetOptimizedCodeForOSR(isolate, function, osr_offset, frame); // With concurrent osr enabled, GetOptimizedCodeForOSR only returns valid
// code at OSROptimizeCodeCache hit.
maybe_result = Compiler::GetOptimizedCodeForOSR(
isolate, function, osr_offset, frame, osr_depth);
} }
// Check whether we ended up with usable optimized code. // Check whether we ended up with usable optimized code.
...@@ -323,15 +338,18 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { ...@@ -323,15 +338,18 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
// feedback. We cannot do this currently since we OSR only after we mark // feedback. We cannot do this currently since we OSR only after we mark
// a function for optimization. We should instead change it to be based // a function for optimization. We should instead change it to be based
// based on number of ticks. // based on number of ticks.
DCHECK(!function->IsInOptimizationQueue()); if (function->IsMarkedForOptimization() ||
function->ClearOptimizationMarker(); function->IsMarkedForConcurrentOptimization()) {
function->ClearOptimizationMarker();
}
} }
// TODO(mythria): Once we have OSR code cache we may not need to mark // TODO(mythria): Once we have OSR code cache we may not need to mark
// the function for non-concurrent compilation. We could arm the loops // the function for non-concurrent compilation. We could arm the loops
// early so the second execution uses the already compiled OSR code and // early so the second execution uses the already compiled OSR code and
// the optimization occurs concurrently off main thread. // the optimization occurs concurrently off main thread.
if (!function->HasAvailableOptimizedCode() && if (!function->HasAvailableOptimizedCode() &&
function->feedback_vector().invocation_count() > 1) { function->feedback_vector().invocation_count() > 1 &&
!function->IsInOptimizationQueue()) {
// If we're not already optimized, set to optimize non-concurrently on // If we're not already optimized, set to optimize non-concurrently on
// the next call, otherwise we'd run unoptimized once more and // the next call, otherwise we'd run unoptimized once more and
// potentially compile for OSR again. // potentially compile for OSR again.
...@@ -344,6 +362,7 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { ...@@ -344,6 +362,7 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
function->SetOptimizationMarker( function->SetOptimizationMarker(
OptimizationMarker::kCompileTurbofan_NotConcurrent); OptimizationMarker::kCompileTurbofan_NotConcurrent);
} }
function->feedback_vector().set_profiler_ticks(0);
return *result; return *result;
} }
} }
......
...@@ -264,6 +264,17 @@ bool CanOptimizeFunction(Handle<JSFunction> function, Isolate* isolate, ...@@ -264,6 +264,17 @@ bool CanOptimizeFunction(Handle<JSFunction> function, Isolate* isolate,
return true; return true;
} }
ConcurrencyMode ConcurrencyModeFromString(Handle<Object> mode,
Isolate* isolate) {
if (mode->IsString() &&
Handle<String>::cast(mode)->IsOneByteEqualTo(
base::StaticCharVector("concurrent")) &&
isolate->concurrent_recompilation_enabled()) {
return ConcurrencyMode::kConcurrent;
}
return ConcurrencyMode::kNotConcurrent;
}
Object OptimizeFunctionOnNextCall(RuntimeArguments& args, Isolate* isolate, Object OptimizeFunctionOnNextCall(RuntimeArguments& args, Isolate* isolate,
TierupKind tierup_kind) { TierupKind tierup_kind) {
if (args.length() != 1 && args.length() != 2) { if (args.length() != 1 && args.length() != 2) {
...@@ -285,11 +296,7 @@ Object OptimizeFunctionOnNextCall(RuntimeArguments& args, Isolate* isolate, ...@@ -285,11 +296,7 @@ Object OptimizeFunctionOnNextCall(RuntimeArguments& args, Isolate* isolate,
if (args.length() == 2) { if (args.length() == 2) {
CONVERT_ARG_HANDLE_CHECKED(Object, type, 1); CONVERT_ARG_HANDLE_CHECKED(Object, type, 1);
if (!type->IsString()) return CrashUnlessFuzzing(isolate); if (!type->IsString()) return CrashUnlessFuzzing(isolate);
if (Handle<String>::cast(type)->IsOneByteEqualTo( concurrency_mode = ConcurrencyModeFromString(type, isolate);
base::StaticCharVector("concurrent")) &&
isolate->concurrent_recompilation_enabled()) {
concurrency_mode = ConcurrencyMode::kConcurrent;
}
} }
if (FLAG_trace_opt) { if (FLAG_trace_opt) {
PrintF("[manually marking "); PrintF("[manually marking ");
...@@ -343,6 +350,14 @@ bool EnsureFeedbackVector(Isolate* isolate, Handle<JSFunction> function) { ...@@ -343,6 +350,14 @@ bool EnsureFeedbackVector(Isolate* isolate, Handle<JSFunction> function) {
return true; return true;
} }
void FinalizeOptimization(Isolate* isolate) {
if (isolate->concurrent_recompilation_enabled()) {
isolate->optimizing_compile_dispatcher()->AwaitCompileTasks();
isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
isolate->optimizing_compile_dispatcher()->set_finalize(true);
}
}
} // namespace } // namespace
RUNTIME_FUNCTION(Runtime_CompileBaseline) { RUNTIME_FUNCTION(Runtime_CompileBaseline) {
...@@ -459,13 +474,13 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionForTopTier) { ...@@ -459,13 +474,13 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionForTopTier) {
RUNTIME_FUNCTION(Runtime_OptimizeOsr) { RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
DCHECK(args.length() == 0 || args.length() == 1); DCHECK(args.length() == 0 || args.length() == 1 || args.length() == 2);
Handle<JSFunction> function; Handle<JSFunction> function;
// The optional parameter determines the frame being targeted. // The first optional parameter determines the frame being targeted.
int stack_depth = 0; int stack_depth = 0;
if (args.length() == 1) { if (args.length() >= 1) {
if (!args[0].IsSmi()) return CrashUnlessFuzzing(isolate); if (!args[0].IsSmi()) return CrashUnlessFuzzing(isolate);
stack_depth = args.smi_at(0); stack_depth = args.smi_at(0);
} }
...@@ -476,6 +491,21 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) { ...@@ -476,6 +491,21 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
if (!it.done()) function = handle(it.frame()->function(), isolate); if (!it.done()) function = handle(it.frame()->function(), isolate);
if (function.is_null()) return CrashUnlessFuzzing(isolate); if (function.is_null()) return CrashUnlessFuzzing(isolate);
if (it.frame()->is_optimized()) {
return ReadOnlyRoots(isolate).undefined_value();
}
if (function->shared().osr_is_in_optimization_queue()) {
FinalizeOptimization(isolate);
return ReadOnlyRoots(isolate).undefined_value();
} else if (function->shared().osr_code_cache_state() !=
OSRCodeCacheStateOfSFI::kNotCached) {
isolate->tiering_manager()->AttemptOnStackReplacement(
UnoptimizedFrame::cast(it.frame()),
AbstractCode::kMaxLoopNestingMarker);
return ReadOnlyRoots(isolate).undefined_value();
}
if (!FLAG_opt) return ReadOnlyRoots(isolate).undefined_value(); if (!FLAG_opt) return ReadOnlyRoots(isolate).undefined_value();
if (!function->shared().allows_lazy_compilation()) { if (!function->shared().allows_lazy_compilation()) {
...@@ -503,18 +533,33 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) { ...@@ -503,18 +533,33 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
return ReadOnlyRoots(isolate).undefined_value(); return ReadOnlyRoots(isolate).undefined_value();
} }
// Ensure that the function is marked for non-concurrent optimization, so that // The second parameter determines the concurrency mode.
// subsequent runs don't also optimize. ConcurrencyMode concurrency_mode = ConcurrencyMode::kNotConcurrent;
if (args.length() == 2) {
CONVERT_ARG_HANDLE_CHECKED(Object, type, 1);
if (!type->IsString()) return CrashUnlessFuzzing(isolate);
concurrency_mode = ConcurrencyModeFromString(type, isolate);
}
if (concurrency_mode == ConcurrencyMode::kNotConcurrent) {
CHECK(!isolate->concurrent_osr_enabled());
} else {
CHECK(isolate->concurrent_osr_enabled());
}
if (FLAG_trace_osr) { if (FLAG_trace_osr) {
CodeTracer::Scope scope(isolate->GetCodeTracer()); CodeTracer::Scope scope(isolate->GetCodeTracer());
PrintF(scope.file(), "[OSR - OptimizeOsr marking "); PrintF(scope.file(), "[OSR - OptimizeOsr marking ");
function->ShortPrint(scope.file()); function->ShortPrint(scope.file());
PrintF(scope.file(), " for non-concurrent optimization]\n"); PrintF(scope.file(), " for %s optimization]\n",
concurrency_mode == ConcurrencyMode::kConcurrent ? "concurrent"
: "non-concurrent");
} }
IsCompiledScope is_compiled_scope( IsCompiledScope is_compiled_scope(
function->shared().is_compiled_scope(isolate)); function->shared().is_compiled_scope(isolate));
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope); JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
function->MarkForOptimization(ConcurrencyMode::kNotConcurrent); function->MarkForOptimization(concurrency_mode);
// Make the profiler arm all back edges in unoptimized code. // Make the profiler arm all back edges in unoptimized code.
if (it.frame()->is_unoptimized()) { if (it.frame()->is_unoptimized()) {
...@@ -672,11 +717,7 @@ RUNTIME_FUNCTION(Runtime_WaitForBackgroundOptimization) { ...@@ -672,11 +717,7 @@ RUNTIME_FUNCTION(Runtime_WaitForBackgroundOptimization) {
RUNTIME_FUNCTION(Runtime_FinalizeOptimization) { RUNTIME_FUNCTION(Runtime_FinalizeOptimization) {
DCHECK_EQ(0, args.length()); DCHECK_EQ(0, args.length());
if (isolate->concurrent_recompilation_enabled()) { FinalizeOptimization(isolate);
isolate->optimizing_compile_dispatcher()->AwaitCompileTasks();
isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
isolate->optimizing_compile_dispatcher()->set_finalize(true);
}
return ReadOnlyRoots(isolate).undefined_value(); return ReadOnlyRoots(isolate).undefined_value();
} }
......
...@@ -28615,7 +28615,7 @@ TEST(FastApiStackSlot) { ...@@ -28615,7 +28615,7 @@ TEST(FastApiStackSlot) {
" let foo = 128;" " let foo = 128;"
" for (let i = 0; i < 100; ++i) {" " for (let i = 0; i < 100; ++i) {"
" let bar = true;" " let bar = true;"
" if (i == 10) %OptimizeOsr();" " if (i == 10 || i == 11) %OptimizeOsr(0, \"concurrent\");"
" try { receiver.api_func(arg) } catch(_) {};" " try { receiver.api_func(arg) } catch(_) {};"
" try { receiver.api_func(arg) } catch(_) {};" " try { receiver.api_func(arg) } catch(_) {};"
" };" " };"
...@@ -2376,7 +2376,7 @@ static const char* pre_profiling_osr_script = R"( ...@@ -2376,7 +2376,7 @@ static const char* pre_profiling_osr_script = R"(
for (let pass = 0; pass <= optDuration + deoptDuration; pass++) { for (let pass = 0; pass <= optDuration + deoptDuration; pass++) {
const startTime = Date.now(); const startTime = Date.now();
// Let a few passes go by to ensure we have enough feeback info // Let a few passes go by to ensure we have enough feeback info
if (pass == 3) %OptimizeOsr(); if (pass == 3 || pass == 4) %OptimizeOsr(0, "concurrent");
// Force deoptimization. %DeoptimizeNow and %DeoptimizeFunction don't // Force deoptimization. %DeoptimizeNow and %DeoptimizeFunction don't
// doptimize OSRs. // doptimize OSRs.
if (pass == optDuration) whenPass = () => {}; if (pass == optDuration) whenPass = () => {};
......
...@@ -271,6 +271,9 @@ class FastJSWasmCallTester { ...@@ -271,6 +271,9 @@ class FastJSWasmCallTester {
i::FLAG_allow_natives_syntax = true; i::FLAG_allow_natives_syntax = true;
i::FLAG_turbo_inline_js_wasm_calls = true; i::FLAG_turbo_inline_js_wasm_calls = true;
i::FLAG_stress_background_compile = false; i::FLAG_stress_background_compile = false;
// Disable concurrent osr to avoid background compilation after test has
// been finished.
i::FLAG_concurrent_osr = false;
} }
void DeclareCallback(const char* name, FunctionSig* signature, void DeclareCallback(const char* name, FunctionSig* signature,
......
...@@ -31,7 +31,7 @@ function ChangeSmiConstantAndOsr() { ...@@ -31,7 +31,7 @@ function ChangeSmiConstantAndOsr() {
var j = 1; var j = 1;
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
if (i == 2) { if (i == 2) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
g(); g();
} }
} }
...@@ -49,7 +49,7 @@ function ChangeFloatConstantAndOsr() { ...@@ -49,7 +49,7 @@ function ChangeFloatConstantAndOsr() {
var j = 0.1; var j = 0.1;
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
if (i == 2) { if (i == 2) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
g(); g();
} }
} }
...@@ -68,7 +68,7 @@ function ChangeFloatVarAndOsr() { ...@@ -68,7 +68,7 @@ function ChangeFloatVarAndOsr() {
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
j = j + 0.1; j = j + 0.1;
if (i == 2) { if (i == 2) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
g(); g();
} }
} }
...@@ -102,7 +102,7 @@ function ChangeIntVarAndOsr() { ...@@ -102,7 +102,7 @@ function ChangeIntVarAndOsr() {
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
j = j + 1|0; j = j + 1|0;
if (i == 2) { if (i == 2) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
g(); g();
} }
} }
......
...@@ -11,7 +11,7 @@ function f() { ...@@ -11,7 +11,7 @@ function f() {
const myObj = {}; const myObj = {};
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%ScheduleBreak(); %ScheduleBreak();
%PrepareFunctionForOptimization(f); %PrepareFunctionForOptimization(f);
} }
......
...@@ -8,7 +8,7 @@ Debug.setListener(function() {}); ...@@ -8,7 +8,7 @@ Debug.setListener(function() {});
function f() { function f() {
for (var i = 0; i < 100; i++) { for (var i = 0; i < 100; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f); %PrepareFunctionForOptimization(f);
} }
} }
......
...@@ -17,7 +17,7 @@ function wrapper1() { ...@@ -17,7 +17,7 @@ function wrapper1() {
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
// Get this function optimized before calling to increment. // Get this function optimized before calling to increment.
// Check that that call performs the necessary side-effect checks. // Check that that call performs the necessary side-effect checks.
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(wrapper1); %PrepareFunctionForOptimization(wrapper1);
} }
f1(); f1();
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --sparkplug --no-always-sparkplug --use-osr
// Flags: --opt --no-always-opt --deopt-every-n-times=0
function isExecutingBaseline(func) {
let opt_status = %GetOptimizationStatus(func);
return (opt_status & V8OptimizationStatus.kTopmostFrameIsBaseline) !== 0;
}
function f() {
for (var i = 0; i <= 20; i++) {
if (i == 5) {
%BaselineOsr();
}
if (i > 5) {
assertTrue(isBaseline(f));
assertTrue(isExecutingBaseline(f));
}
}
}
%NeverOptimizeFunction(f);
f();
var expectedStatus = V8OptimizationStatus.kTopmostFrameIsInterpreted;
function checkTopmostFrame(func) {
let opt_status = %GetOptimizationStatus(func);
assertTrue ((opt_status & expectedStatus) !== 0, "Expected flag " +
expectedStatus + " to be set in optimization status");
}
function g() {
for (var i = 0; i <= 20; i++) {
if (i == 6) {
let opt_status = %GetOptimizationStatus(g);
if ((V8OptimizationStatus.kTopmostFrameIsTurboFanned & opt_status) !== 0) {
console.log("quit for concurrent osr not enabled.");
testRunner.quit(0);
}
}
checkTopmostFrame(g)
if (i == 2) {
%BaselineOsr();
expectedStatus = V8OptimizationStatus.kTopmostFrameIsBaseline;
}
if (i == 5) {
%OptimizeOsr(0, "concurrent");
}
if (i == 6) {
%FinalizeOptimization();
expectedStatus = V8OptimizationStatus.kTopmostFrameIsTurboFanned;
}
}
}
%PrepareFunctionForOptimization(g);
g();
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --sparkplug --no-always-sparkplug --use-osr // Flags: --allow-natives-syntax --sparkplug --no-always-sparkplug --use-osr
// Flags: --opt --no-always-opt --deopt-every-n-times=0 // Flags: --opt --no-always-opt --deopt-every-n-times=0 --no-concurrent-osr
function isExecutingBaseline(func) { function isExecutingBaseline(func) {
let opt_status = %GetOptimizationStatus(func); let opt_status = %GetOptimizationStatus(func);
......
...@@ -53,7 +53,7 @@ function createSource(name, fillCnt) { ...@@ -53,7 +53,7 @@ function createSource(name, fillCnt) {
} }
src += src +=
` if (i == 5) { ` if (i == 5) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PretenureAllocationSite(local_arr); %PretenureAllocationSite(local_arr);
} }
} }
......
...@@ -262,7 +262,8 @@ function osr_inner(t, limit) { ...@@ -262,7 +262,8 @@ function osr_inner(t, limit) {
if (t.hasOwnProperty(x)) { if (t.hasOwnProperty(x)) {
for (var i = 0; i < t[x].length; i++) { for (var i = 0; i < t[x].length; i++) {
r += t[x][i]; r += t[x][i];
if (i === limit) %OptimizeOsr(); if (i === limit) %OptimizeOsr(0, "concurrent");
%FinalizeOptimization();
} }
r += x; r += x;
} }
...@@ -278,7 +279,8 @@ function osr_outer(t, osr_after) { ...@@ -278,7 +279,8 @@ function osr_outer(t, osr_after) {
for (var i = 0; i < t[x].length; i++) { for (var i = 0; i < t[x].length; i++) {
r += t[x][i]; r += t[x][i];
} }
if (x === osr_after) %OptimizeOsr(); if (x === osr_after) %OptimizeOsr(0, "concurrent");
%FinalizeOptimization();
r += x; r += x;
} }
return r; return r;
...@@ -289,7 +291,8 @@ function osr_outer_and_deopt(t, osr_after) { ...@@ -289,7 +291,8 @@ function osr_outer_and_deopt(t, osr_after) {
var r = 1; var r = 1;
for (var x in t) { for (var x in t) {
r += x; r += x;
if (x == osr_after) %OptimizeOsr(); if (x == osr_after) %OptimizeOsr(0, "concurrent");
%FinalizeOptimization();
} }
return r; return r;
} }
......
...@@ -34,7 +34,7 @@ function f1() { ...@@ -34,7 +34,7 @@ function f1() {
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
sum += z; sum += z;
if (i == 18) %OptimizeOsr(); if (i >= 18) %OptimizeOsr(0, "concurrent");
} }
return sum; return sum;
} }
...@@ -46,7 +46,7 @@ function f2() { ...@@ -46,7 +46,7 @@ function f2() {
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
sum += z; sum += z;
if (i == 19) %OptimizeOsr(); if (i >= 19) %OptimizeOsr(0, "concurrent");
} }
return sum; return sum;
} }
...@@ -58,7 +58,7 @@ function f3() { ...@@ -58,7 +58,7 @@ function f3() {
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
sum += z; sum += z;
if (i == 20) %OptimizeOsr(); if (i >= 20) %OptimizeOsr(0, "concurrent");
} }
return sum; return sum;
} }
......
...@@ -8,7 +8,7 @@ function f1() { ...@@ -8,7 +8,7 @@ function f1() {
var sum = 0; var sum = 0;
for (var i = 0; i < 1000; i++) { for (var i = 0; i < 1000; i++) {
sum += arguments[0] + arguments[1] + arguments[2] + arguments[3]; sum += arguments[0] + arguments[1] + arguments[2] + arguments[3];
if (i == 18) %OptimizeOsr(); if (i == 18 || i == 19) %OptimizeOsr(0, "concurrent");
} }
return sum; return sum;
} }
......
...@@ -9,7 +9,7 @@ function fastaRandom(n, table) { ...@@ -9,7 +9,7 @@ function fastaRandom(n, table) {
var line = new Array(5); var line = new Array(5);
while (n > 0) { while (n > 0) {
if (n < line.length) line = new Array(n); if (n < line.length) line = new Array(n);
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
line[0] = n; line[0] = n;
n--; n--;
%PrepareFunctionForOptimization(fastaRandom); %PrepareFunctionForOptimization(fastaRandom);
......
...@@ -34,8 +34,8 @@ function f(x, b, c) { ...@@ -34,8 +34,8 @@ function f(x, b, c) {
a = a + 5; a = a + 5;
assertEquals(b + 1, c); assertEquals(b + 1, c);
outer--; outer--;
if (outer === 5) { if (outer === 5 || outer === 4) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
} }
return a + 4; return a + 4;
......
...@@ -15,7 +15,7 @@ function foo(a) { ...@@ -15,7 +15,7 @@ function foo(a) {
if (i == 5) { i = 6; continue; } if (i == 5) { i = 6; continue; }
if (i == 6) { i = 7; continue; } if (i == 6) { i = 7; continue; }
if (i == 7) { i = 8; continue; } if (i == 7) { i = 8; continue; }
for (var j = 0; j < 10; j++) { if (i == 5) %OptimizeOsr(); } for (var j = 0; j < 10; j++) { if (i == 5) %OptimizeOsr(0, "concurrent"); }
break; break;
} }
return j; return j;
......
...@@ -11,7 +11,7 @@ function foo() { ...@@ -11,7 +11,7 @@ function foo() {
{ {
let sum = 0; let sum = 0;
for (var i = 0; i < 100; i++) { for (var i = 0; i < 100; i++) {
if (i == 50) %OptimizeOsr(); if (i == 50 || i == 51) %OptimizeOsr(0, "concurrent");
sum += i; sum += i;
} }
result = ret; result = ret;
......
...@@ -14,7 +14,7 @@ function foo() { ...@@ -14,7 +14,7 @@ function foo() {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
{ {
let x = i; let x = i;
if (i == 5) %OptimizeOsr(); if (i == 5 || i == 6) %OptimizeOsr(0, "concurrent");
sum += i; sum += i;
result.push(function() { return x; }); result.push(function() { return x; });
} }
......
...@@ -51,7 +51,7 @@ function foo() { ...@@ -51,7 +51,7 @@ function foo() {
{ {
let sum = 0; let sum = 0;
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
sum += i; sum += i;
%PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(foo);
} }
...@@ -66,7 +66,7 @@ test(45, foo); ...@@ -66,7 +66,7 @@ test(45, foo);
function bar() { function bar() {
let sum = 0; let sum = 0;
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
sum += i; sum += i;
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
} }
...@@ -80,7 +80,7 @@ function bon() { ...@@ -80,7 +80,7 @@ function bon() {
{ {
let sum = 0; let sum = 0;
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
if (i == 5) %OptimizeOsr(); if (i == 5) %OptimizeOsr(0, "concurrent");
sum += i; sum += i;
} }
return sum; return sum;
...@@ -96,7 +96,7 @@ function row() { ...@@ -96,7 +96,7 @@ function row() {
let sum = 0; let sum = 0;
while (true) { while (true) {
if (i == 8) return sum; if (i == 8) return sum;
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
sum = i; sum = i;
i = i + 1 | 0; i = i + 1 | 0;
%PrepareFunctionForOptimization(row); %PrepareFunctionForOptimization(row);
...@@ -111,7 +111,7 @@ test(7, row); ...@@ -111,7 +111,7 @@ test(7, row);
function nub() { function nub() {
let i = 0; let i = 0;
while (i < 2) { while (i < 2) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
i++; i++;
%PrepareFunctionForOptimization(nub); %PrepareFunctionForOptimization(nub);
} }
...@@ -126,7 +126,7 @@ function kub() { ...@@ -126,7 +126,7 @@ function kub() {
let i = 0; let i = 0;
while (i < 2) { while (i < 2) {
let x = i; let x = i;
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
i++; i++;
result = x; result = x;
%PrepareFunctionForOptimization(kub); %PrepareFunctionForOptimization(kub);
......
...@@ -21,7 +21,7 @@ function bar() { ...@@ -21,7 +21,7 @@ function bar() {
let sum = 0; let sum = 0;
for (let i = 0; i < 90; i++) { for (let i = 0; i < 90; i++) {
sum += i; sum += i;
if (i == 45) %OptimizeOsr(); if (i == 45 || i == 46) %OptimizeOsr(0, "concurrent");
} }
result = sum; result = sum;
} }
...@@ -33,10 +33,10 @@ test(4005, bar); ...@@ -33,10 +33,10 @@ test(4005, bar);
function baz() { function baz() {
let sum = 0; let sum = 0;
for (let i = 0; i < 2; i++) { for (let i = 0; i < 3; i++) {
%PrepareFunctionForOptimization(baz); %PrepareFunctionForOptimization(baz);
sum = 2; sum = 2;
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
return sum; return sum;
} }
...@@ -45,30 +45,30 @@ test(2, baz); ...@@ -45,30 +45,30 @@ test(2, baz);
function qux() { function qux() {
var result = 0; var result = 0;
for (let i = 0; i < 2; i++) { for (let i = 0; i < 3; i++) {
%PrepareFunctionForOptimization(qux); %PrepareFunctionForOptimization(qux);
result = i; result = i;
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
return result; return result;
} }
test(1, qux); test(2, qux);
function nux() { function nux() {
var result = 0; var result = 0;
for (let i = 0; i < 2; i++) { for (let i = 0; i < 3; i++) {
{ {
%PrepareFunctionForOptimization(nux); %PrepareFunctionForOptimization(nux);
let sum = i; let sum = i;
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
result = sum; result = sum;
} }
} }
return result; return result;
} }
test(1, nux); test(2, nux);
function blo() { function blo() {
var result; var result;
...@@ -76,7 +76,7 @@ function blo() { ...@@ -76,7 +76,7 @@ function blo() {
let sum = 0; let sum = 0;
for (let i = 0; i < 90; i++) { for (let i = 0; i < 90; i++) {
sum += i; sum += i;
if (i == 45) %OptimizeOsr(); if (i == 45 || i == 46) %OptimizeOsr(0, "concurrent");
} }
result = ret; result = ret;
function ret() { function ret() {
......
...@@ -12,8 +12,8 @@ function test(e, f, v) { ...@@ -12,8 +12,8 @@ function test(e, f, v) {
function foo(t) { function foo(t) {
for (var x in t) { for (var x in t) {
for (var i = 0; i < 2; i++) { for (var i = 0; i < 3; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(foo);
} }
} }
...@@ -26,8 +26,8 @@ test(5, foo, {x:20}); ...@@ -26,8 +26,8 @@ test(5, foo, {x:20});
function bar(t) { function bar(t) {
var sum = 0; var sum = 0;
for (var x in t) { for (var x in t) {
for (var i = 0; i < 2; i++) { for (var i = 0; i < 3; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
sum += t[x]; sum += t[x];
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
} }
...@@ -36,4 +36,4 @@ function bar(t) { ...@@ -36,4 +36,4 @@ function bar(t) {
} }
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
test(62, bar, {x:20,y:11}); test(93, bar, {x:20,y:11});
...@@ -8,7 +8,7 @@ var global_counter = 0; ...@@ -8,7 +8,7 @@ var global_counter = 0;
function thrower() { function thrower() {
var x = global_counter++; var x = global_counter++;
if (x == 5) %OptimizeOsr(1); if (x == 5 || x == 6) %OptimizeOsr(1, "concurrent");
if (x == 10) throw "terminate"; if (x == 10) throw "terminate";
} }
......
...@@ -10,7 +10,7 @@ function foo() { ...@@ -10,7 +10,7 @@ function foo() {
B: for (var j = 0; j < 5; j++) { B: for (var j = 0; j < 5; j++) {
%PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(foo);
C: for (var k = 0; k < 10; k++) { C: for (var k = 0; k < 10; k++) {
if (k === 5) %OptimizeOsr(); if (k === 4 || k === 5) %OptimizeOsr(0, "concurrent");
if (k === 6) break B; if (k === 6) break B;
sum++; sum++;
} }
...@@ -30,7 +30,7 @@ function bar(a) { ...@@ -30,7 +30,7 @@ function bar(a) {
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
C: for (var k = 0; k < 10; k++) { C: for (var k = 0; k < 10; k++) {
sum++; sum++;
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
if (a === 1) break A; if (a === 1) break A;
if (a === 2) break B; if (a === 2) break B;
if (a === 3) break C; if (a === 3) break C;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
function mod() { function mod() {
function f0() { function f0() {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 3; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f0); %PrepareFunctionForOptimization(f0);
} }
return {blah: i}; return {blah: i};
...@@ -16,7 +16,7 @@ function mod() { ...@@ -16,7 +16,7 @@ function mod() {
function f1(a) { function f1(a) {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 3; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f1); %PrepareFunctionForOptimization(f1);
} }
return {blah: i}; return {blah: i};
...@@ -25,7 +25,7 @@ function mod() { ...@@ -25,7 +25,7 @@ function mod() {
function f2(a,b) { function f2(a,b) {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 3; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f2); %PrepareFunctionForOptimization(f2);
} }
return {blah: i}; return {blah: i};
...@@ -34,7 +34,7 @@ function mod() { ...@@ -34,7 +34,7 @@ function mod() {
function f3(a,b,c) { function f3(a,b,c) {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 3; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f3); %PrepareFunctionForOptimization(f3);
} }
return {blah: i}; return {blah: i};
...@@ -43,7 +43,7 @@ function mod() { ...@@ -43,7 +43,7 @@ function mod() {
function f4(a,b,c,d) { function f4(a,b,c,d) {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 3; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f4); %PrepareFunctionForOptimization(f4);
} }
return {blah: i}; return {blah: i};
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
function mod() { function mod() {
function f0() { function f0() {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 4; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f0); %PrepareFunctionForOptimization(f0);
} }
return {blah: i}; return {blah: i};
...@@ -15,8 +15,8 @@ function mod() { ...@@ -15,8 +15,8 @@ function mod() {
%PrepareFunctionForOptimization(f0); %PrepareFunctionForOptimization(f0);
function f1(a) { function f1(a) {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 4; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f1); %PrepareFunctionForOptimization(f1);
} }
return {blah: i}; return {blah: i};
...@@ -24,8 +24,8 @@ function mod() { ...@@ -24,8 +24,8 @@ function mod() {
%PrepareFunctionForOptimization(f1); %PrepareFunctionForOptimization(f1);
function f2(a,b) { function f2(a,b) {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 4; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f2); %PrepareFunctionForOptimization(f2);
} }
return {blah: i}; return {blah: i};
...@@ -33,8 +33,8 @@ function mod() { ...@@ -33,8 +33,8 @@ function mod() {
%PrepareFunctionForOptimization(f2); %PrepareFunctionForOptimization(f2);
function f3(a,b,c) { function f3(a,b,c) {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 4; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f3); %PrepareFunctionForOptimization(f3);
} }
return {blah: i}; return {blah: i};
...@@ -42,8 +42,8 @@ function mod() { ...@@ -42,8 +42,8 @@ function mod() {
%PrepareFunctionForOptimization(f3); %PrepareFunctionForOptimization(f3);
function f4(a,b,c,d) { function f4(a,b,c,d) {
for (var i = 0; i < 3; i = i + 1 | 0) { for (var i = 0; i < 4; i = i + 1 | 0) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f4); %PrepareFunctionForOptimization(f4);
} }
return {blah: i}; return {blah: i};
...@@ -51,11 +51,11 @@ function mod() { ...@@ -51,11 +51,11 @@ function mod() {
%PrepareFunctionForOptimization(f4); %PrepareFunctionForOptimization(f4);
function bar() { function bar() {
assertEquals(3, f0().blah); assertEquals(4, f0().blah);
assertEquals(3, f1(1).blah); assertEquals(4, f1(1).blah);
assertEquals(3, f2(1,2).blah); assertEquals(4, f2(1,2).blah);
assertEquals(3, f3(1,2,3).blah); assertEquals(4, f3(1,2,3).blah);
assertEquals(3, f4(1,2,3,4).blah); assertEquals(4, f4(1,2,3,4).blah);
} }
bar(); bar();
} }
......
...@@ -9,7 +9,7 @@ var counter = 111; ...@@ -9,7 +9,7 @@ var counter = 111;
function gen(w) { // defeat compiler cache. function gen(w) { // defeat compiler cache.
var num = counter++; var num = counter++;
var Z = [ "", "", "", ]; var Z = [ "", "", "", ];
Z[w] = "%OptimizeOsr(); %PrepareFunctionForOptimization(f" + num + ")"; Z[w] = "%OptimizeOsr(0, \"concurrent\"); %PrepareFunctionForOptimization(f" + num + ")";
var src = var src =
"function f" + num + "(a,b,c) {" + "function f" + num + "(a,b,c) {" +
" var x = 0;" + " var x = 0;" +
......
...@@ -9,7 +9,7 @@ var counter = 188; ...@@ -9,7 +9,7 @@ var counter = 188;
function gen(w) { // defeat compiler cache. function gen(w) { // defeat compiler cache.
var num = counter++; var num = counter++;
var Z = [ "", "", "", ]; var Z = [ "", "", "", ];
Z[w] = "%OptimizeOsr(); %PrepareFunctionForOptimization(f" + num + ")"; Z[w] = "%OptimizeOsr(0, \"concurrent\"); %PrepareFunctionForOptimization(f" + num + ")";
var src = var src =
"function f" + num + "(a,b,c) {" + "function f" + num + "(a,b,c) {" +
" var x = 0;" + " var x = 0;" +
......
...@@ -10,43 +10,43 @@ function bar(goal) { ...@@ -10,43 +10,43 @@ function bar(goal) {
var i = 35; var i = 35;
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
while (i-- > 33) { while (i-- > 33) {
if (count++ == goal) %OptimizeOsr(); if (count++ == goal || count == goal + 1) %OptimizeOsr(0, "concurrent");
sum = sum + i; sum = sum + i;
} }
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
while (i-- > 31) { while (i-- > 31) {
if (count++ == goal) %OptimizeOsr(); if (count++ == goal || count == goal + 1) %OptimizeOsr(0, "concurrent");
j = 9; j = 9;
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
while (j-- > 7) { while (j-- > 7) {
if (count++ == goal) %OptimizeOsr(); if (count++ == goal || count == goal + 1) %OptimizeOsr(0, "concurrent");
sum = sum + j * 3; sum = sum + j * 3;
} }
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
while (j-- > 5) { while (j-- > 5) {
if (count++ == goal) %OptimizeOsr(); if (count++ == goal || count == goal + 1) %OptimizeOsr(0, "concurrent");
sum = sum + j * 5; sum = sum + j * 5;
} }
} }
while (i-- > 29) { while (i-- > 29) {
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
if (count++ == goal) %OptimizeOsr(); if (count++ == goal || count == goal + 1) %OptimizeOsr(0, "concurrent");
while (j-- > 3) { while (j-- > 3) {
var k = 10; var k = 10;
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
if (count++ == goal) %OptimizeOsr(); if (count++ == goal || count == goal + 1) %OptimizeOsr(0, "concurrent");
while (k-- > 8) { while (k-- > 8) {
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
if (count++ == goal) %OptimizeOsr(); if (count++ == goal || count == goal + 1) %OptimizeOsr(0, "concurrent");
sum = sum + k * 11; sum = sum + k * 11;
} }
} }
while (j-- > 1) { while (j-- > 1) {
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
if (count++ == goal) %OptimizeOsr(); if (count++ == goal || count == goal + 1) %OptimizeOsr(0, "concurrent");
while (k-- > 6) { while (k-- > 6) {
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
if (count++ == goal) %OptimizeOsr(); if (count++ == goal || count == goal + 1) %OptimizeOsr(0, "concurrent");
sum = sum + j * 13; sum = sum + j * 13;
} }
} }
......
...@@ -51,7 +51,7 @@ function gen(i) { ...@@ -51,7 +51,7 @@ function gen(i) {
body = body.replace(new RegExp("bar"), "bar" + i); body = body.replace(new RegExp("bar"), "bar" + i);
for (var j = 1; j < 10; j++) { for (var j = 1; j < 10; j++) {
var r = new RegExp("LOOP" + j + "\\(\\);"); var r = new RegExp("LOOP" + j + "\\(\\);");
if (i == j) body = body.replace(r, "%OptimizeOsr(); %PrepareFunctionForOptimization(bar" + i +");"); if (i == j || i == j + 1) body = body.replace(r, "%OptimizeOsr(0, \"concurrent\"); %PrepareFunctionForOptimization(bar" + i +");");
else body = body.replace(r, ""); else body = body.replace(r, "");
} }
return eval("(" + body + ")"); return eval("(" + body + ")");
......
...@@ -36,7 +36,7 @@ function f() { ...@@ -36,7 +36,7 @@ function f() {
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
sum += z; sum += z;
if (j == 5) %OptimizeOsr(); if (j == 5 || j == 6) %OptimizeOsr(0, "concurrent");
} }
} }
return sum; return sum;
......
...@@ -12,7 +12,7 @@ function f() { ...@@ -12,7 +12,7 @@ function f() {
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
sum += z; sum += z;
if (i == 21) %OptimizeOsr(); if (i == 21) %OptimizeOsr(0, "concurrent");
} }
} }
return sum; return sum;
......
...@@ -12,7 +12,7 @@ function f() { ...@@ -12,7 +12,7 @@ function f() {
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
sum += z; sum += z;
if (i == 25) %OptimizeOsr(); if (i == 25) %OptimizeOsr(0, "concurrent");
} }
if (true) break; if (true) break;
} }
......
...@@ -13,7 +13,7 @@ function f() { ...@@ -13,7 +13,7 @@ function f() {
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
sum += z; sum += z;
if (i == 19) %OptimizeOsr(); if (i == 19) %OptimizeOsr(0, "concurrent");
} }
} }
} }
......
...@@ -13,7 +13,7 @@ function f() { ...@@ -13,7 +13,7 @@ function f() {
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
sum += z; sum += z;
if (i == 25) %OptimizeOsr(); if (i == 25) %OptimizeOsr(0, "concurrent");
} }
if (true) break; if (true) break;
} }
......
...@@ -10,8 +10,8 @@ function f(x) { ...@@ -10,8 +10,8 @@ function f(x) {
while (count > 0) { while (count > 0) {
sum += x; sum += x;
count--; count--;
if (count == 5) { if (count == 5 || count == 4) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
} }
return sum; return sum;
......
...@@ -9,7 +9,7 @@ function id(f) { return f; } ...@@ -9,7 +9,7 @@ function id(f) { return f; }
function foo(a) { function foo(a) {
var r = /\0/; var r = /\0/;
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
if (a) %OptimizeOsr(); if (a) %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(foo);
} }
return r; return r;
...@@ -18,7 +18,7 @@ function foo(a) { ...@@ -18,7 +18,7 @@ function foo(a) {
function bar(a) { function bar(a) {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
if (a) %OptimizeOsr(); if (a) %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(bar);
var r = /\0/; var r = /\0/;
} }
...@@ -28,7 +28,7 @@ function bar(a) { ...@@ -28,7 +28,7 @@ function bar(a) {
function baz(a) { function baz(a) {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
if (a) %OptimizeOsr(); if (a) %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(baz); %PrepareFunctionForOptimization(baz);
} }
return /\0/; return /\0/;
...@@ -38,7 +38,7 @@ function baz(a) { ...@@ -38,7 +38,7 @@ function baz(a) {
function qux(a) { function qux(a) {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
if (i > 5 && a) { if (i > 5 && a) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(qux); %PrepareFunctionForOptimization(qux);
} else { } else {
var r = /\0/; var r = /\0/;
......
...@@ -11,7 +11,7 @@ function f() { ...@@ -11,7 +11,7 @@ function f() {
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
sum += z; sum += z;
if (i == 11) %OptimizeOsr(); if (i == 11 || i == 12) %OptimizeOsr(0, "concurrent");
} }
return sum; return sum;
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
function f() { function f() {
var sum = 0; var sum = 0;
for (var i = 0; i < 10000; i++) { for (var i = 0; i < 10000; i++) {
if (i == 100) %OptimizeOsr(); if (i == 100 || i == 101) %OptimizeOsr(0, "concurrent");
var x = i + 2; var x = i + 2;
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
......
...@@ -8,7 +8,7 @@ function f() { ...@@ -8,7 +8,7 @@ function f() {
for (var j = 0; j < 3; j++) { for (var j = 0; j < 3; j++) {
var sum = 0; var sum = 0;
for (var i = 0; i < 1000; i++) { for (var i = 0; i < 1000; i++) {
if (i == 100) %OptimizeOsr(); if (i == 100 || i == 101) %OptimizeOsr(0, "concurrent");
var x = i + 2; var x = i + 2;
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
......
...@@ -9,7 +9,7 @@ function f() { ...@@ -9,7 +9,7 @@ function f() {
for (var j = 0; j < 3; j++) { for (var j = 0; j < 3; j++) {
var sum = 0; var sum = 0;
for (var i = 0; i < 1000; i++) { for (var i = 0; i < 1000; i++) {
if (i == 100) %OptimizeOsr(); if (i == 100 || i == 101) %OptimizeOsr(0, "concurrent");
var x = i + 2; var x = i + 2;
var y = x + 5; var y = x + 5;
var z = y + 3; var z = y + 3;
......
...@@ -14,8 +14,8 @@ function SingleLoop() { ...@@ -14,8 +14,8 @@ function SingleLoop() {
for (var a = 0; a < 2; a++) { for (var a = 0; a < 2; a++) {
try { throw 'The exception should have been caught.'; } try { throw 'The exception should have been caught.'; }
catch(e) {} catch(e) {}
for (var b = 0; b < 1; b++) { for (var b = 0; b < 2; b++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(SingleLoop); %PrepareFunctionForOptimization(SingleLoop);
} }
} }
...@@ -33,10 +33,10 @@ function EmptyBody() { ...@@ -33,10 +33,10 @@ function EmptyBody() {
try {; } catch(e) {; } try {; } catch(e) {; }
var a = 0; var a = 0;
while (1) { while (1) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
print("foo"); print("foo");
if (a == 1) break; if (a == 2) break;
a++; a++;
%PrepareFunctionForOptimization(EmptyBody); %PrepareFunctionForOptimization(EmptyBody);
} }
...@@ -46,12 +46,12 @@ function EmptyBody() { ...@@ -46,12 +46,12 @@ function EmptyBody() {
function NestedLoops() { function NestedLoops() {
for (var a = 0; a < 2; a++) { for (var a = 0; a < 2; a++) {
try {; } catch(e) {; } try {; } catch(e) {; }
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
var b = 0; var b = 0;
while (1) { while (1) {
print("bar"); print("bar");
if (b == 1) break; if (b == 2) break;
b++; b++;
} }
%PrepareFunctionForOptimization(NestedLoops); %PrepareFunctionForOptimization(NestedLoops);
......
...@@ -12,8 +12,8 @@ function f(x) { ...@@ -12,8 +12,8 @@ function f(x) {
while (inner > 0) { while (inner > 0) {
sum += x; sum += x;
inner--; inner--;
if (inner == 5) { if (inner == 5 || inner == 4) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
} }
outer--; outer--;
......
...@@ -25,7 +25,7 @@ function foo() { ...@@ -25,7 +25,7 @@ function foo() {
var flag = 1; var flag = 1;
for (; flag == 1; (flag = 0, temp_x = x)) { for (; flag == 1; (flag = 0, temp_x = x)) {
if (x < 2) { if (x < 2) {
result = x; %OptimizeOsr(); result = x; %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(foo);
} else { } else {
break outer; break outer;
...@@ -48,7 +48,7 @@ function smo() { ...@@ -48,7 +48,7 @@ function smo() {
outer: while (true) { outer: while (true) {
let y = x; let y = x;
for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(smo); %PrepareFunctionForOptimization(smo);
if (i) break outer; if (i) break outer;
else result = y; else result = y;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
for (var x in a) { for (var x in a) {
try { try {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(g); %PrepareFunctionForOptimization(g);
} }
return; return;
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
for (var x in a) { for (var x in a) {
if (x) { if (x) {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(g); %PrepareFunctionForOptimization(g);
} }
} }
......
...@@ -9,7 +9,7 @@ function f() { ...@@ -9,7 +9,7 @@ function f() {
while (1) { while (1) {
for (var j = 0; j < 200; j -= j) { for (var j = 0; j < 200; j -= j) {
sum = sum + 1; sum = sum + 1;
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
if (sum == 2) return; if (sum == 2) return;
%PrepareFunctionForOptimization(f); %PrepareFunctionForOptimization(f);
} }
......
...@@ -8,7 +8,7 @@ function f() { ...@@ -8,7 +8,7 @@ function f() {
var x = 0; var x = 0;
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
x = (2 % x) | 0; x = (2 % x) | 0;
if (i === 5) %OptimizeOsr(); if (i === 5 || i === 6) %OptimizeOsr(0, "concurrent");
} }
return x; return x;
} }
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
"use asm"; "use asm";
var f = function() { var f = function() {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
if (i == 5) { if (i == 5 || i == 6) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
} }
with (Object()); with (Object());
......
...@@ -8,7 +8,7 @@ function f() { ...@@ -8,7 +8,7 @@ function f() {
var accumulator = false; var accumulator = false;
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
accumulator = accumulator.hasOwnProperty(3); accumulator = accumulator.hasOwnProperty(3);
if (i === 1) %OptimizeOsr(); if (i === 1 || i === 2) %OptimizeOsr(0, "concurrent");
} }
} }
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax
function foo() { function foo() {
for (var a = 0; a < 2; a++) { for (var a = 0; a < 3; a++) {
if (a === 1) %OptimizeOsr(); if (a === 1 || a === 2) %OptimizeOsr(0, "concurrent");
while (0 && 1) { while (0 && 1) {
for (var j = 1; j < 2; j++) { } for (var j = 1; j < 2; j++) { }
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
function f(get, ...a) { function f(get, ...a) {
for (let i = 0; i < 1000; i++) { for (let i = 0; i < 1000; i++) {
if (i === 999) %OptimizeOsr(); if (i === 998 || i === 999) %OptimizeOsr(0, "concurrent");
a.map(f); a.map(f);
} }
return get(); return get();
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
function OSRInsideTry(x) { function OSRInsideTry(x) {
try { try {
for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); } for (var i = 0; i < 10; i++) { if (i > 5) %OptimizeOsr(0, "concurrent"); }
throw x; throw x;
} catch (e) { } catch (e) {
return e + 1; return e + 1;
...@@ -21,7 +21,7 @@ function OSRInsideCatch(x) { ...@@ -21,7 +21,7 @@ function OSRInsideCatch(x) {
try { try {
throw x; throw x;
} catch (e) { } catch (e) {
for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); } for (var i = 0; i < 10; i++) { if (i > 5) %OptimizeOsr(0, "concurrent"); }
return e + 1; return e + 1;
} }
return x + 2; return x + 2;
...@@ -34,7 +34,7 @@ function OSRInsideFinally_Return(x) { ...@@ -34,7 +34,7 @@ function OSRInsideFinally_Return(x) {
try { try {
throw x; throw x;
} finally { } finally {
for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); } for (var i = 0; i < 10; i++) { if (i > 5) %OptimizeOsr(0, "concurrent"); }
return x + 1; return x + 1;
} }
return x + 2; return x + 2;
...@@ -47,7 +47,7 @@ function OSRInsideFinally_ReThrow(x) { ...@@ -47,7 +47,7 @@ function OSRInsideFinally_ReThrow(x) {
try { try {
throw x; throw x;
} finally { } finally {
for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); } for (var i = 0; i < 10; i++) { if (i > 5) %OptimizeOsr(0, "concurrent"); }
} }
return x + 2; return x + 2;
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
function f() { function f() {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
if (i == 5) %OptimizeOsr(); if (i == 5 || i == 6) %OptimizeOsr(0, "concurrent");
} }
} }
%PrepareFunctionForOptimization(f); %PrepareFunctionForOptimization(f);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
(function TestGeneratorOSRSimple() { (function TestGeneratorOSRSimple() {
function* gen1() { function* gen1() {
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 3; ++i) {
if (i == 1) %OptimizeOsr(); if (i >= 1) %OptimizeOsr(0, "concurrent");
} }
return 23; return 23;
} }
...@@ -19,7 +19,10 @@ ...@@ -19,7 +19,10 @@
(function TestGeneratorOSRYieldAfterArming() { (function TestGeneratorOSRYieldAfterArming() {
function* gen2() { function* gen2() {
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 3; ++i) {
if (i == 1) %OptimizeOsr(); if (i == 1 || i == 2) {
%PrepareFunctionForOptimization(gen2);
%OptimizeOsr(0, "concurrent");
}
yield i; yield i;
} }
return 23; return 23;
...@@ -36,7 +39,7 @@ ...@@ -36,7 +39,7 @@
function* gen3() { function* gen3() {
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 3; ++i) {
yield i; yield i;
if (i == 1) %OptimizeOsr(); if (i >= 1) %OptimizeOsr(0, "concurrent");
} }
return 23; return 23;
} }
...@@ -53,7 +56,7 @@ ...@@ -53,7 +56,7 @@
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 3; ++i) {
for (var j = 0; j < 3; ++j) { for (var j = 0; j < 3; ++j) {
for (var k = 0; k < 10; ++k) { for (var k = 0; k < 10; ++k) {
if (k == 5) %OptimizeOsr(); if (k == 5 || k == 6) %OptimizeOsr(0, "concurrent");
} }
%PrepareFunctionForOptimization(gen4); %PrepareFunctionForOptimization(gen4);
} }
......
...@@ -92,7 +92,7 @@ function test_osr_elements_kind() { ...@@ -92,7 +92,7 @@ function test_osr_elements_kind() {
%NeverOptimizeFunction(construct_smis); %NeverOptimizeFunction(construct_smis);
%NeverOptimizeFunction(construct_doubles); %NeverOptimizeFunction(construct_doubles);
%NeverOptimizeFunction(convert_mixed); %NeverOptimizeFunction(convert_mixed);
for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); } for (var i = 0; i < 10; i++) { if (i == 5 || i == 6) %OptimizeOsr(0, "concurrent"); }
// This code exists to eliminate the learning influence of AllocationSites // This code exists to eliminate the learning influence of AllocationSites
// on the following tests. // on the following tests.
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
var dummy = deopt + 0; var dummy = deopt + 0;
for (var i = 0; osr && i < 2; i++) { for (var i = 0; osr && i < 2; i++) {
%PrepareFunctionForOptimization(f); %PrepareFunctionForOptimization(f);
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
return result; return result;
} }
......
...@@ -33,7 +33,7 @@ function f(deopt, osr) { ...@@ -33,7 +33,7 @@ function f(deopt, osr) {
var dummy = deopt + 0; var dummy = deopt + 0;
for (var i = 0; osr && i < 2; i++) { for (var i = 0; osr && i < 2; i++) {
%PrepareFunctionForOptimization(f); %PrepareFunctionForOptimization(f);
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
return result; return result;
} }
......
...@@ -15,7 +15,7 @@ function v0() { ...@@ -15,7 +15,7 @@ function v0() {
function v1() { function v1() {
while (!v0()) { while (!v0()) {
// Trigger OSR early to get a crashing case asap. // Trigger OSR early to get a crashing case asap.
if (ticks == 5) %OptimizeOsr(); if (ticks >= 5 && ticks < 10) %OptimizeOsr(0, "concurrent");
// With the bug fixed, there's no easy way to trigger termination. Instead, // With the bug fixed, there's no easy way to trigger termination. Instead,
// run until we reach a certain number of ticks. The crash triggers locally // run until we reach a certain number of ticks. The crash triggers locally
// at tick 7562, thus running until 20k ticks to be somewhat safe. // at tick 7562, thus running until 20k ticks to be somewhat safe.
......
...@@ -47,7 +47,7 @@ function g() { try { return o.f(); } finally { }} ...@@ -47,7 +47,7 @@ function g() { try { return o.f(); } finally { }}
// This function should be optimized via OSR. // This function should be optimized via OSR.
function h() { function h() {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(h); %PrepareFunctionForOptimization(h);
} }
g(); g();
......
...@@ -18,8 +18,8 @@ function foo () { ...@@ -18,8 +18,8 @@ function foo () {
l = 0; l = 0;
break; break;
case 0: case 0:
if (cnt++ == 5) { if (cnt++ == 5 || cnt == 6) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
l = 1; l = 1;
} }
break; break;
......
...@@ -39,7 +39,7 @@ function f() { ...@@ -39,7 +39,7 @@ function f() {
do { do {
do { do {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f); %PrepareFunctionForOptimization(f);
} }
// Note: this check can't be wrapped in a function, because // Note: this check can't be wrapped in a function, because
...@@ -74,7 +74,7 @@ function g() { ...@@ -74,7 +74,7 @@ function g() {
do { do {
do { do {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(g); %PrepareFunctionForOptimization(g);
} }
var opt_status = %GetOptimizationStatus(g); var opt_status = %GetOptimizationStatus(g);
......
...@@ -11,7 +11,7 @@ function Cb(a, trigger) { ...@@ -11,7 +11,7 @@ function Cb(a, trigger) {
// This will fail after OSR if Runtime_StringCharCodeAt is modified // This will fail after OSR if Runtime_StringCharCodeAt is modified
// to iterates optimized frames and visit safepoint pointers. // to iterates optimized frames and visit safepoint pointers.
if (g == "C".charCodeAt(0)) { if (g == "C".charCodeAt(0)) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(Cb); %PrepareFunctionForOptimization(Cb);
} }
} }
...@@ -24,7 +24,7 @@ var s2 = "long string to make cons string 2"; ...@@ -24,7 +24,7 @@ var s2 = "long string to make cons string 2";
Cb(s1 + s2); Cb(s1 + s2);
%PrepareFunctionForOptimization(Cb); %PrepareFunctionForOptimization(Cb);
Cb(s1); Cb(s1);
var s3 = "string for triggering osr in Cb"; var s3 = "string for triggering osr in CCb";
%PrepareFunctionForOptimization(Cb); %PrepareFunctionForOptimization(Cb);
Cb(s3 + s3); Cb(s3 + s3);
%PrepareFunctionForOptimization(Cb); %PrepareFunctionForOptimization(Cb);
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax
function f() { function f() {
for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); } for (var i = 0; i < 10; i++) { if (i == 5 || i == 6) %OptimizeOsr(0, "concurrent"); }
var xl = 4096; var xl = 4096;
var z = i % xl; var z = i % xl;
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
function foo(obj) { function foo(obj) {
var counter = 1; var counter = 1;
for (var i = 0; i < obj.length; i++) { for (var i = 0; i < obj.length; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(foo);
} }
counter += obj; counter += obj;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
(function TestNonLoopyLoop() { (function TestNonLoopyLoop() {
function f() { function f() {
do { do {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
return 23; return 23;
} while(false) } while(false)
} }
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
(function TestNonLoopyGenerator() { (function TestNonLoopyGenerator() {
function* g() { function* g() {
do { do {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
yield 23; yield 23;
yield 42; yield 42;
} while(false) } while(false)
......
...@@ -10,7 +10,7 @@ function boom(o) { o.g = h } ...@@ -10,7 +10,7 @@ function boom(o) { o.g = h }
function f(osr_and_recurse) { function f(osr_and_recurse) {
if (osr_and_recurse) { if (osr_and_recurse) {
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 3; ++i) {
if (i == 1) %OptimizeOsr(); if (i >= 1) %OptimizeOsr(0, "concurrent");
} }
%PrepareFunctionForOptimization(f); %PrepareFunctionForOptimization(f);
%OptimizeFunctionOnNextCall(f); %OptimizeFunctionOnNextCall(f);
......
...@@ -10,7 +10,7 @@ var f = (function() { ...@@ -10,7 +10,7 @@ var f = (function() {
"use asm"; "use asm";
return function g(c1, c2) { return function g(c1, c2) {
for (var x = 0 ; x < 10; ++x) { for (var x = 0 ; x < 10; ++x) {
if (x == 5) %OptimizeOsr(); if (x == 5 || x == 6) %OptimizeOsr(0, "concurrent");
c1(); c1();
} }
} }
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
function f() { function f() {
var C = class {}; var C = class {};
for (var i = 0; i < 4; ++i) { for (var i = 0; i < 5; ++i) {
if (i == 2) %OptimizeOsr(); if (i >= 2) %OptimizeOsr(0, "concurrent");
C.prototype.foo = 42; C.prototype.foo = 42;
} }
} }
......
...@@ -8,7 +8,10 @@ function f() { ...@@ -8,7 +8,10 @@ function f() {
C = class {}; C = class {};
for (var i = 0; i < 5; ++i) { for (var i = 0; i < 5; ++i) {
gc(); gc();
if (i == 2) %OptimizeOsr(); if (i == 2 || i == 3) {
%OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(f);
}
C.prototype.foo = i + 9000000000000000; C.prototype.foo = i + 9000000000000000;
} }
} }
......
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
// //
// Flags: --allow-natives-syntax --fuzzing --no-testing-d8-test-runner // Flags: --allow-natives-syntax --fuzzing --no-testing-d8-test-runner
[1,2,3].reduceRight(() => { %OptimizeOsr(1); }); [1,2,3].reduceRight(() => { %OptimizeOsr(1, "concurrent"); });
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
function outer() { function outer() {
inner(1,2,3); inner(1,2,3);
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(outer); %PrepareFunctionForOptimization(outer);
} }
} }
......
...@@ -12,7 +12,7 @@ function f() { ...@@ -12,7 +12,7 @@ function f() {
function g() { function g() {
for (var i = 0; i < 300; i++) { for (var i = 0; i < 300; i++) {
f(); f();
if (i == 150) %OptimizeOsr(); if (i == 150 || i == 151) %OptimizeOsr(0, "concurrent");
} }
} }
%PrepareFunctionForOptimization(g); %PrepareFunctionForOptimization(g);
...@@ -10,8 +10,8 @@ function foo() { ...@@ -10,8 +10,8 @@ function foo() {
for (var a = 1; a > 0; a--) { for (var a = 1; a > 0; a--) {
c += 1; c += 1;
} }
for (var b = 1; b > 0; b--) { for (var b = 2; b > 0; b--) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
} }
return c; return c;
......
...@@ -10,10 +10,10 @@ ...@@ -10,10 +10,10 @@
function makeFun() { function makeFun() {
function fun(osr_fuse) { function fun(osr_fuse) {
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 3; ++i) {
if (i == osr_fuse) %OptimizeOsr(); if (i >= osr_fuse) %OptimizeOsr(0, "concurrent");
} }
for (var i = 3; i < 6; ++i) { for (var i = 3; i < 6; ++i) {
if (i == osr_fuse) %OptimizeOsr(); if (i >= osr_fuse) %OptimizeOsr(0, "concurrent");
} }
} }
%PrepareFunctionForOptimization(fun); %PrepareFunctionForOptimization(fun);
......
...@@ -8,7 +8,7 @@ var body = ...@@ -8,7 +8,7 @@ var body =
"function bar1( ) {" + "function bar1( ) {" +
" var i = 35; " + " var i = 35; " +
" while (i-- > 31) {" + " while (i-- > 31) {" +
" %OptimizeOsr(); " + " %OptimizeOsr(0, \"concurrent\"); " +
" j = 9; " + " j = 9; " +
" %PrepareFunctionForOptimization(bar1); " + " %PrepareFunctionForOptimization(bar1); " +
" while (j-- > 7);" + " while (j-- > 7);" +
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
// Flags: --allow-natives-syntax --expose-gc --no-lazy // Flags: --allow-natives-syntax --expose-gc --no-lazy
function f() { function f() {
for (var i = 0; i < 10; i++) if (i == 5) %OptimizeOsr(); for (var i = 0; i < 10; i++) if (i == 5 || i == 6) %OptimizeOsr(0, "concurrent");
function g() {} function g() {}
%PrepareFunctionForOptimization(g); %PrepareFunctionForOptimization(g);
%OptimizeFunctionOnNextCall(g); %OptimizeFunctionOnNextCall(g);
......
...@@ -10,7 +10,7 @@ function A() { ...@@ -10,7 +10,7 @@ function A() {
} }
%EnsureFeedbackVectorForFunction(A); %EnsureFeedbackVectorForFunction(A);
function foo() { function foo() {
for (var i = 0; i < 1; i = 2) %OptimizeOsr(); for (var i = 0; i < 2; i++) %OptimizeOsr(0, "concurrent");
return new A(); return new A();
} }
%PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(foo);
......
...@@ -7,7 +7,10 @@ ...@@ -7,7 +7,10 @@
function f() { function f() {
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 3; ++i) {
if (i == 1) { if (i == 1) {
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
}
if (i == 2) {
%OptimizeOsr(0, "concurrent");
break; // Trigger next loop. break; // Trigger next loop.
} }
} }
......
...@@ -12,7 +12,7 @@ function f() { ...@@ -12,7 +12,7 @@ function f() {
function g() { function g() {
try { f(); } catch(e) { } try { f(); } catch(e) { }
%PrepareFunctionForOptimization(g); %PrepareFunctionForOptimization(g);
for (var i = 0; i < 3; ++i) if (i === 1) %OptimizeOsr(); for (var i = 0; i < 3; ++i) %OptimizeOsr(0, "concurrent");
%_DeoptimizeNow(); %_DeoptimizeNow();
} }
%PrepareFunctionForOptimization(g); %PrepareFunctionForOptimization(g);
......
...@@ -9,7 +9,7 @@ function f() { ...@@ -9,7 +9,7 @@ function f() {
for (var i = 0; i < 4; ++i) { for (var i = 0; i < 4; ++i) {
var x = a[0]; var x = a[0];
(function() { return x }); (function() { return x });
if (i == 1) %OptimizeOsr(); if (i == 1 || i == 2) %OptimizeOsr(0, "concurrent");
gc(); gc();
} }
} }
......
...@@ -10,8 +10,8 @@ function g() { ...@@ -10,8 +10,8 @@ function g() {
function f() { function f() {
var result = "R:"; var result = "R:";
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 4; ++i) {
if (i == 1) %OptimizeOsr(); if (i == 1 || i == 2) %OptimizeOsr(0, "concurrent");
result += g([1])[0]; result += g([1])[0];
result += g([2])[0]; result += g([2])[0];
} }
...@@ -19,4 +19,4 @@ function f() { ...@@ -19,4 +19,4 @@ function f() {
} }
%PrepareFunctionForOptimization(f); %PrepareFunctionForOptimization(f);
assertEquals("R:121212", f()); assertEquals("R:12121212", f());
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
// elided. // elided.
with(f&&g&&(s()=N)({...g})){} with(f&&g&&(s()=N)({...g})){}
} catch {} } catch {}
%OptimizeOsr(); %OptimizeOsr(0, "concurrent");
} }
} }
%EnsureFeedbackVectorForFunction(f); %EnsureFeedbackVectorForFunction(f);
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
for (let i = 0; i < 5; ++i) { for (let i = 0; i < 5; ++i) {
a--; // Make sure {a} is non-immutable, hence context allocated. a--; // Make sure {a} is non-immutable, hence context allocated.
function g() { return i } // Make sure block has a context. function g() { return i } // Make sure block has a context.
if (i == 2) %OptimizeOsr(); if (i == 2 || i == 3) %OptimizeOsr(0, "concurrent");
} }
return a; return a;
} }
......
...@@ -12,8 +12,11 @@ function get_closure() { ...@@ -12,8 +12,11 @@ function get_closure() {
return function add_field(obj, osr) { return function add_field(obj, osr) {
obj.c = 3; obj.c = 3;
var x = 0; var x = 0;
if (osr) %OptimizeOsr();
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
if (osr && %IsBeingInterpreted()) {
%OptimizeOsr(0, "concurrent");
%PrepareFunctionForOptimization(add_field);
}
x = i + 1; x = i + 1;
} }
return x; return x;
......
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