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

Side by Side Diff: src/runtime.cc

Issue 23710014: Introduce concurrent on-stack replacement. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 7 years, 3 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/platform/mutex.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 8319 matching lines...) Expand 10 before | Expand all | Expand 10 after
8330 RUNTIME_FUNCTION(MaybeObject*, Runtime_ConcurrentRecompile) { 8330 RUNTIME_FUNCTION(MaybeObject*, Runtime_ConcurrentRecompile) {
8331 HandleScope handle_scope(isolate); 8331 HandleScope handle_scope(isolate);
8332 ASSERT(args.length() == 1); 8332 ASSERT(args.length() == 1);
8333 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 8333 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8334 if (!AllowOptimization(isolate, function)) { 8334 if (!AllowOptimization(isolate, function)) {
8335 function->ReplaceCode(function->shared()->code()); 8335 function->ReplaceCode(function->shared()->code());
8336 return isolate->heap()->undefined_value(); 8336 return isolate->heap()->undefined_value();
8337 } 8337 }
8338 function->shared()->code()->set_profiler_ticks(0); 8338 function->shared()->code()->set_profiler_ticks(0);
8339 ASSERT(FLAG_concurrent_recompilation); 8339 ASSERT(FLAG_concurrent_recompilation);
8340 Compiler::RecompileConcurrent(function); 8340 if (!Compiler::RecompileConcurrent(function)) {
8341 function->ReplaceCode(function->shared()->code());
8342 }
8341 return isolate->heap()->undefined_value(); 8343 return isolate->heap()->undefined_value();
8342 } 8344 }
8343 8345
8344 8346
8345 RUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) { 8347 RUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) {
8346 HandleScope handle_scope(isolate); 8348 HandleScope handle_scope(isolate);
8347 ASSERT(args.length() == 1); 8349 ASSERT(args.length() == 1);
8348 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 8350 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8349 ASSERT(V8::UseCrankshaft() && FLAG_concurrent_recompilation); 8351 ASSERT(V8::UseCrankshaft() && FLAG_concurrent_recompilation);
8350 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); 8352 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
8499 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 8501 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8500 8502
8501 if (!function->IsOptimizable()) return isolate->heap()->undefined_value(); 8503 if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
8502 function->MarkForLazyRecompilation(); 8504 function->MarkForLazyRecompilation();
8503 8505
8504 Code* unoptimized = function->shared()->code(); 8506 Code* unoptimized = function->shared()->code();
8505 if (args.length() == 2 && 8507 if (args.length() == 2 &&
8506 unoptimized->kind() == Code::FUNCTION) { 8508 unoptimized->kind() == Code::FUNCTION) {
8507 CONVERT_ARG_HANDLE_CHECKED(String, type, 1); 8509 CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
8508 if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) { 8510 if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
8509 for (int i = 0; i <= Code::kMaxLoopNestingMarker; i++) { 8511 // Start patching from the currently patched loop nesting level.
8512 int current_level = unoptimized->allow_osr_at_loop_nesting_level();
8513 ASSERT(Deoptimizer::VerifyInterruptCode(
8514 isolate, unoptimized, current_level));
8515 for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) {
8510 unoptimized->set_allow_osr_at_loop_nesting_level(i); 8516 unoptimized->set_allow_osr_at_loop_nesting_level(i);
8511 isolate->runtime_profiler()->AttemptOnStackReplacement(*function); 8517 isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
8512 } 8518 }
8513 } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent"))) { 8519 } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent"))) {
8514 function->MarkForConcurrentRecompilation(); 8520 function->MarkForConcurrentRecompilation();
8515 } 8521 }
8516 } 8522 }
8517 8523
8518 return isolate->heap()->undefined_value(); 8524 return isolate->heap()->undefined_value();
8519 } 8525 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
8573 8579
8574 8580
8575 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) { 8581 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
8576 HandleScope scope(isolate); 8582 HandleScope scope(isolate);
8577 ASSERT(args.length() == 1); 8583 ASSERT(args.length() == 1);
8578 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 8584 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8579 8585
8580 // We're not prepared to handle a function with arguments object. 8586 // We're not prepared to handle a function with arguments object.
8581 ASSERT(!function->shared()->uses_arguments()); 8587 ASSERT(!function->shared()->uses_arguments());
8582 8588
8583 // We have hit a back edge in an unoptimized frame for a function that was
8584 // selected for on-stack replacement. Find the unoptimized code object.
8585 Handle<Code> unoptimized(function->shared()->code(), isolate);
8586 // Keep track of whether we've succeeded in optimizing.
8587 bool succeeded = unoptimized->optimizable();
8588 if (succeeded) {
8589 // If we are trying to do OSR when there are already optimized
8590 // activations of the function, it means (a) the function is directly or
8591 // indirectly recursive and (b) an optimized invocation has been
8592 // deoptimized so that we are currently in an unoptimized activation.
8593 // Check for optimized activations of this function.
8594 JavaScriptFrameIterator it(isolate);
8595 while (succeeded && !it.done()) {
8596 JavaScriptFrame* frame = it.frame();
8597 succeeded = !frame->is_optimized() || frame->function() != *function;
8598 it.Advance();
8599 }
8600 }
8601
8602 BailoutId ast_id = BailoutId::None();
8603 if (succeeded) {
8604 // The top JS function is this one, the PC is somewhere in the
8605 // unoptimized code.
8606 JavaScriptFrameIterator it(isolate);
8607 JavaScriptFrame* frame = it.frame();
8608 ASSERT(frame->function() == *function);
8609 ASSERT(frame->LookupCode() == *unoptimized);
8610 ASSERT(unoptimized->contains(frame->pc()));
8611
8612 // Use linear search of the unoptimized code's back edge table to find
8613 // the AST id matching the PC.
8614 uint32_t target_pc_offset =
8615 static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start());
8616 uint32_t loop_depth = 0;
8617
8618 for (FullCodeGenerator::BackEdgeTableIterator back_edges(*unoptimized);
8619 !back_edges.Done();
8620 back_edges.Next()) {
8621 if (back_edges.pc_offset() == target_pc_offset) {
8622 ast_id = back_edges.ast_id();
8623 loop_depth = back_edges.loop_depth();
8624 break;
8625 }
8626 }
8627 ASSERT(!ast_id.IsNone());
8628
8629 if (FLAG_trace_osr) {
8630 PrintF("[replacing on-stack at AST id %d, loop depth %d in ",
8631 ast_id.ToInt(), loop_depth);
8632 function->PrintName();
8633 PrintF("]\n");
8634 }
8635
8636 // Try to compile the optimized code. A true return value from
8637 // CompileOptimized means that compilation succeeded, not necessarily
8638 // that optimization succeeded.
8639 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
8640 function->IsOptimized()) {
8641 DeoptimizationInputData* data = DeoptimizationInputData::cast(
8642 function->code()->deoptimization_data());
8643 if (data->OsrPcOffset()->value() >= 0) {
8644 if (FLAG_trace_osr) {
8645 PrintF("[on-stack replacement offset %d in optimized code]\n",
8646 data->OsrPcOffset()->value());
8647 }
8648 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
8649 } else {
8650 // We may never generate the desired OSR entry if we emit an
8651 // early deoptimize.
8652 succeeded = false;
8653 }
8654 } else {
8655 succeeded = false;
8656 }
8657 }
8658
8659 // Revert to the original interrupt calls in the original unoptimized code.
8660 if (FLAG_trace_osr) {
8661 PrintF("[restoring original interrupt calls in ");
8662 function->PrintName();
8663 PrintF("]\n");
8664 }
8665 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
8666
8667 // If the optimization attempt succeeded, return the AST id tagged as a 8589 // If the optimization attempt succeeded, return the AST id tagged as a
8668 // smi. This tells the builtin that we need to translate the unoptimized 8590 // smi. This tells the builtin that we need to translate the unoptimized
8669 // frame to an optimized one. 8591 // frame to an optimized one.
8670 if (succeeded) { 8592 BailoutId ast_id =
8593 (FLAG_concurrent_recompilation && FLAG_concurrent_osr)
8594 ? Compiler::CompileForConcurrentOSR(function)
8595 : Compiler::CompileForOnStackReplacement(function);
8596 if (!ast_id.IsNone()) {
8671 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); 8597 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
8672 return Smi::FromInt(ast_id.ToInt()); 8598 return Smi::FromInt(ast_id.ToInt());
8673 } else { 8599 } else {
8674 if (function->IsMarkedForLazyRecompilation()) { 8600 if (function->IsMarkedForLazyRecompilation() ||
8601 function->IsMarkedForConcurrentRecompilation()) {
8675 function->ReplaceCode(function->shared()->code()); 8602 function->ReplaceCode(function->shared()->code());
8676 } 8603 }
8677 return Smi::FromInt(-1); 8604 return Smi::FromInt(-1);
8678 } 8605 }
8679 } 8606 }
8680 8607
8681 8608
8682 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) { 8609 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) {
8683 SealHandleScope shs(isolate); 8610 SealHandleScope shs(isolate);
8684 ASSERT(args.length() == 2); 8611 ASSERT(args.length() == 2);
(...skipping 6010 matching lines...) Expand 10 before | Expand all | Expand 10 after
14695 // Handle last resort GC and make sure to allow future allocations 14622 // Handle last resort GC and make sure to allow future allocations
14696 // to grow the heap without causing GCs (if possible). 14623 // to grow the heap without causing GCs (if possible).
14697 isolate->counters()->gc_last_resort_from_js()->Increment(); 14624 isolate->counters()->gc_last_resort_from_js()->Increment();
14698 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14625 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14699 "Runtime::PerformGC"); 14626 "Runtime::PerformGC");
14700 } 14627 }
14701 } 14628 }
14702 14629
14703 14630
14704 } } // namespace v8::internal 14631 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform/mutex.h ('k') | src/runtime-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698