Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/runtime.cc

Issue 13811014: Fix OSR for nested loops. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects-inl.h ('k') | src/runtime-profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 25 matching lines...) Expand all
36 #include "bootstrapper.h" 36 #include "bootstrapper.h"
37 #include "codegen.h" 37 #include "codegen.h"
38 #include "compilation-cache.h" 38 #include "compilation-cache.h"
39 #include "compiler.h" 39 #include "compiler.h"
40 #include "cpu.h" 40 #include "cpu.h"
41 #include "dateparser-inl.h" 41 #include "dateparser-inl.h"
42 #include "debug.h" 42 #include "debug.h"
43 #include "deoptimizer.h" 43 #include "deoptimizer.h"
44 #include "date.h" 44 #include "date.h"
45 #include "execution.h" 45 #include "execution.h"
46 #include "full-codegen.h"
46 #include "global-handles.h" 47 #include "global-handles.h"
47 #include "isolate-inl.h" 48 #include "isolate-inl.h"
48 #include "jsregexp.h" 49 #include "jsregexp.h"
49 #include "jsregexp-inl.h" 50 #include "jsregexp-inl.h"
50 #include "json-parser.h" 51 #include "json-parser.h"
51 #include "json-stringifier.h" 52 #include "json-stringifier.h"
52 #include "liveedit.h" 53 #include "liveedit.h"
53 #include "misc-intrinsics.h" 54 #include "misc-intrinsics.h"
54 #include "parser.h" 55 #include "parser.h"
55 #include "platform.h" 56 #include "platform.h"
(...skipping 7546 matching lines...) Expand 10 before | Expand all | Expand 10 after
7602 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 7603 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
7603 7604
7604 if (!function->IsOptimizable()) return isolate->heap()->undefined_value(); 7605 if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
7605 function->MarkForLazyRecompilation(); 7606 function->MarkForLazyRecompilation();
7606 7607
7607 Code* unoptimized = function->shared()->code(); 7608 Code* unoptimized = function->shared()->code();
7608 if (args.length() == 2 && 7609 if (args.length() == 2 &&
7609 unoptimized->kind() == Code::FUNCTION) { 7610 unoptimized->kind() == Code::FUNCTION) {
7610 CONVERT_ARG_HANDLE_CHECKED(String, type, 1); 7611 CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
7611 if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) { 7612 if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
7612 isolate->runtime_profiler()->AttemptOnStackReplacement(*function); 7613 for (int i = 0; i <= Code::kMaxLoopNestingMarker; i++) {
7613 unoptimized->set_allow_osr_at_loop_nesting_level( 7614 unoptimized->set_allow_osr_at_loop_nesting_level(i);
7614 Code::kMaxLoopNestingMarker); 7615 isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
7616 }
7615 } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("parallel"))) { 7617 } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("parallel"))) {
7616 function->MarkForParallelRecompilation(); 7618 function->MarkForParallelRecompilation();
7617 } 7619 }
7618 } 7620 }
7619 7621
7620 return isolate->heap()->undefined_value(); 7622 return isolate->heap()->undefined_value();
7621 } 7623 }
7622 7624
7623 7625
7624 RUNTIME_FUNCTION(MaybeObject*, Runtime_WaitUntilOptimized) { 7626 RUNTIME_FUNCTION(MaybeObject*, Runtime_WaitUntilOptimized) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
7697 BailoutId ast_id = BailoutId::None(); 7699 BailoutId ast_id = BailoutId::None();
7698 if (succeeded) { 7700 if (succeeded) {
7699 // The top JS function is this one, the PC is somewhere in the 7701 // The top JS function is this one, the PC is somewhere in the
7700 // unoptimized code. 7702 // unoptimized code.
7701 JavaScriptFrameIterator it(isolate); 7703 JavaScriptFrameIterator it(isolate);
7702 JavaScriptFrame* frame = it.frame(); 7704 JavaScriptFrame* frame = it.frame();
7703 ASSERT(frame->function() == *function); 7705 ASSERT(frame->function() == *function);
7704 ASSERT(frame->LookupCode() == *unoptimized); 7706 ASSERT(frame->LookupCode() == *unoptimized);
7705 ASSERT(unoptimized->contains(frame->pc())); 7707 ASSERT(unoptimized->contains(frame->pc()));
7706 7708
7707 // Use linear search of the unoptimized code's stack check table to find 7709 // Use linear search of the unoptimized code's back edge table to find
7708 // the AST id matching the PC. 7710 // the AST id matching the PC.
7709 Address start = unoptimized->instruction_start(); 7711 Address start = unoptimized->instruction_start();
7710 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); 7712 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start);
7711 Address table_cursor = start + unoptimized->stack_check_table_offset(); 7713 Address table_cursor = start + unoptimized->back_edge_table_offset();
7712 uint32_t table_length = Memory::uint32_at(table_cursor); 7714 uint32_t table_length = Memory::uint32_at(table_cursor);
7713 table_cursor += kIntSize; 7715 table_cursor += kIntSize;
7716 uint8_t loop_depth = 0;
7714 for (unsigned i = 0; i < table_length; ++i) { 7717 for (unsigned i = 0; i < table_length; ++i) {
7715 // Table entries are (AST id, pc offset) pairs. 7718 // Table entries are (AST id, pc offset) pairs.
7716 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize); 7719 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize);
7717 if (pc_offset == target_pc_offset) { 7720 if (pc_offset == target_pc_offset) {
7718 ast_id = BailoutId(static_cast<int>(Memory::uint32_at(table_cursor))); 7721 ast_id = BailoutId(static_cast<int>(Memory::uint32_at(table_cursor)));
7722 loop_depth = Memory::uint8_at(table_cursor + 2 * kIntSize);
7719 break; 7723 break;
7720 } 7724 }
7721 table_cursor += 2 * kIntSize; 7725 table_cursor += FullCodeGenerator::kBackEdgeEntrySize;
7722 } 7726 }
7723 ASSERT(!ast_id.IsNone()); 7727 ASSERT(!ast_id.IsNone());
7724 if (FLAG_trace_osr) { 7728 if (FLAG_trace_osr) {
7725 PrintF("[replacing on-stack at AST id %d in ", ast_id.ToInt()); 7729 PrintF("[replacing on-stack at AST id %d, loop depth %d in ",
7730 ast_id.ToInt(), loop_depth);
7726 function->PrintName(); 7731 function->PrintName();
7727 PrintF("]\n"); 7732 PrintF("]\n");
7728 } 7733 }
7729 7734
7730 // Try to compile the optimized code. A true return value from 7735 // Try to compile the optimized code. A true return value from
7731 // CompileOptimized means that compilation succeeded, not necessarily 7736 // CompileOptimized means that compilation succeeded, not necessarily
7732 // that optimization succeeded. 7737 // that optimization succeeded.
7733 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && 7738 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
7734 function->IsOptimized()) { 7739 function->IsOptimized()) {
7735 DeoptimizationInputData* data = DeoptimizationInputData::cast( 7740 DeoptimizationInputData* data = DeoptimizationInputData::cast(
7736 function->code()->deoptimization_data()); 7741 function->code()->deoptimization_data());
7737 if (data->OsrPcOffset()->value() >= 0) { 7742 if (data->OsrPcOffset()->value() >= 0) {
7738 if (FLAG_trace_osr) { 7743 if (FLAG_trace_osr) {
7739 PrintF("[on-stack replacement offset %d in optimized code]\n", 7744 PrintF("[on-stack replacement offset %d in optimized code]\n",
7740 data->OsrPcOffset()->value()); 7745 data->OsrPcOffset()->value());
7741 } 7746 }
7742 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id); 7747 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
7743 } else { 7748 } else {
7744 // We may never generate the desired OSR entry if we emit an 7749 // We may never generate the desired OSR entry if we emit an
7745 // early deoptimize. 7750 // early deoptimize.
7746 succeeded = false; 7751 succeeded = false;
7747 } 7752 }
7748 } else { 7753 } else {
7749 succeeded = false; 7754 succeeded = false;
7750 } 7755 }
7751 } 7756 }
7752 7757
7753 // Revert to the original stack checks in the original unoptimized code. 7758 // Revert to the original interrupt calls in the original unoptimized code.
7754 if (FLAG_trace_osr) { 7759 if (FLAG_trace_osr) {
7755 PrintF("[restoring original stack checks in "); 7760 PrintF("[restoring original interrupt calls in ");
7756 function->PrintName(); 7761 function->PrintName();
7757 PrintF("]\n"); 7762 PrintF("]\n");
7758 } 7763 }
7759 InterruptStub interrupt_stub; 7764 InterruptStub interrupt_stub;
7760 Handle<Code> check_code = interrupt_stub.GetCode(isolate); 7765 Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate);
7761 Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement(); 7766 Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement();
7762 Deoptimizer::RevertStackCheckCode(*unoptimized, 7767 Deoptimizer::RevertInterruptCode(*unoptimized,
7763 *check_code, 7768 *interrupt_code,
7764 *replacement_code); 7769 *replacement_code);
7765 7770
7766 // Allow OSR only at nesting level zero again. 7771 // Allow OSR only at nesting level zero again.
7767 unoptimized->set_allow_osr_at_loop_nesting_level(0); 7772 unoptimized->set_allow_osr_at_loop_nesting_level(0);
7768 7773
7769 // If the optimization attempt succeeded, return the AST id tagged as a 7774 // If the optimization attempt succeeded, return the AST id tagged as a
7770 // smi. This tells the builtin that we need to translate the unoptimized 7775 // smi. This tells the builtin that we need to translate the unoptimized
7771 // frame to an optimized one. 7776 // frame to an optimized one.
7772 if (succeeded) { 7777 if (succeeded) {
7773 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); 7778 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
7774 return Smi::FromInt(ast_id.ToInt()); 7779 return Smi::FromInt(ast_id.ToInt());
(...skipping 5276 matching lines...) Expand 10 before | Expand all | Expand 10 after
13051 // Handle last resort GC and make sure to allow future allocations 13056 // Handle last resort GC and make sure to allow future allocations
13052 // to grow the heap without causing GCs (if possible). 13057 // to grow the heap without causing GCs (if possible).
13053 isolate->counters()->gc_last_resort_from_js()->Increment(); 13058 isolate->counters()->gc_last_resort_from_js()->Increment();
13054 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13059 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13055 "Runtime::PerformGC"); 13060 "Runtime::PerformGC");
13056 } 13061 }
13057 } 13062 }
13058 13063
13059 13064
13060 } } // namespace v8::internal 13065 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects-inl.h ('k') | src/runtime-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698