Commit b863016d authored by yangguo@chromium.org's avatar yangguo@chromium.org

Inhibit OSR for big functions.

R=jkummerow@chromium.org
BUG=

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

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