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

Side by Side Diff: src/runtime.cc

Issue 21340002: Generate a custom OSR entrypoint for OSR compiles on all platforms, and transition to optimized cod… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use FixedArray::OffsetAt and add comment to codegen. Created 7 years, 4 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.cc ('k') | src/x64/builtins-x64.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 8121 matching lines...) Expand 10 before | Expand all | Expand 10 after
8132 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) { 8132 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
8133 HandleScope scope(isolate); 8133 HandleScope scope(isolate);
8134 ASSERT(args.length() == 1); 8134 ASSERT(args.length() == 1);
8135 Handle<JSFunction> function = args.at<JSFunction>(0); 8135 Handle<JSFunction> function = args.at<JSFunction>(0);
8136 8136
8137 if (!AllowOptimization(isolate, function)) { 8137 if (!AllowOptimization(isolate, function)) {
8138 function->ReplaceCode(function->shared()->code()); 8138 function->ReplaceCode(function->shared()->code());
8139 return function->code(); 8139 return function->code();
8140 } 8140 }
8141 function->shared()->code()->set_profiler_ticks(0); 8141 function->shared()->code()->set_profiler_ticks(0);
8142 if (JSFunction::CompileOptimized(function, 8142 if (JSFunction::CompileOptimized(function, CLEAR_EXCEPTION)) {
8143 BailoutId::None(),
8144 CLEAR_EXCEPTION)) {
8145 return function->code(); 8143 return function->code();
8146 } 8144 }
8147 if (FLAG_trace_opt) { 8145 if (FLAG_trace_opt) {
8148 PrintF("[failed to optimize "); 8146 PrintF("[failed to optimize ");
8149 function->PrintName(); 8147 function->PrintName();
8150 PrintF(": optimized compilation failed]\n"); 8148 PrintF(": optimized compilation failed]\n");
8151 } 8149 }
8152 function->ReplaceCode(function->shared()->code()); 8150 function->ReplaceCode(function->shared()->code());
8153 return function->code(); 8151 return function->code();
8154 } 8152 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
8216 8214
8217 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { 8215 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
8218 HandleScope scope(isolate); 8216 HandleScope scope(isolate);
8219 ASSERT(args.length() == 1); 8217 ASSERT(args.length() == 1);
8220 RUNTIME_ASSERT(args[0]->IsSmi()); 8218 RUNTIME_ASSERT(args[0]->IsSmi());
8221 Deoptimizer::BailoutType type = 8219 Deoptimizer::BailoutType type =
8222 static_cast<Deoptimizer::BailoutType>(args.smi_at(0)); 8220 static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
8223 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); 8221 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
8224 ASSERT(AllowHeapAllocation::IsAllowed()); 8222 ASSERT(AllowHeapAllocation::IsAllowed());
8225 8223
8226 ASSERT(deoptimizer->compiled_code_kind() == Code::OPTIMIZED_FUNCTION); 8224 Handle<Code> optimized_code(deoptimizer->compiled_code());
8225 ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
8226
8227 Handle<JSFunction> function(deoptimizer->function());
8228 ASSERT(!function.is_null());
8227 8229
8228 // Make sure to materialize objects before causing any allocation. 8230 // Make sure to materialize objects before causing any allocation.
8229 JavaScriptFrameIterator it(isolate); 8231 JavaScriptFrameIterator it(isolate);
8230 deoptimizer->MaterializeHeapObjects(&it); 8232 deoptimizer->MaterializeHeapObjects(&it);
8231 delete deoptimizer; 8233 delete deoptimizer;
8232 8234
8233 JavaScriptFrame* frame = it.frame(); 8235 JavaScriptFrame* frame = it.frame();
8234 RUNTIME_ASSERT(frame->function()->IsJSFunction());
8235 Handle<JSFunction> function(frame->function(), isolate);
8236 Handle<Code> optimized_code(function->code());
8237 RUNTIME_ASSERT((type != Deoptimizer::EAGER &&
8238 type != Deoptimizer::SOFT) || function->IsOptimized());
8239 8236
8237 ASSERT(frame->function() == *function);
8240 // Avoid doing too much work when running with --always-opt and keep 8238 // Avoid doing too much work when running with --always-opt and keep
8241 // the optimized code around. 8239 // the optimized code around.
8242 if (FLAG_always_opt || type == Deoptimizer::LAZY) { 8240 if (FLAG_always_opt || type == Deoptimizer::LAZY) {
8243 return isolate->heap()->undefined_value(); 8241 return isolate->heap()->undefined_value();
8244 } 8242 }
8245 8243
8246 // Find other optimized activations of the function or functions that 8244 // Find other activations of the optimized code.
8247 // share the same optimized code.
8248 bool has_other_activations = false; 8245 bool has_other_activations = false;
8249 while (!it.done()) { 8246 while (!it.done()) {
8250 JavaScriptFrame* frame = it.frame(); 8247 if (it.frame()->function()->code() == *optimized_code) {
Michael Starzinger 2013/08/01 09:25:30 Yep, this method is looking good to me now.
8251 JSFunction* other_function = frame->function();
8252 if (frame->is_optimized() && other_function->code() == function->code()) {
8253 has_other_activations = true; 8248 has_other_activations = true;
8254 break; 8249 break;
8255 } 8250 }
8256 it.Advance(); 8251 it.Advance();
8257 } 8252 }
8258 8253
8259 if (!has_other_activations) { 8254 if (!has_other_activations) {
8260 ActivationsFinder activations_finder(*function); 8255 ActivationsFinder activations_finder(*function);
8261 isolate->thread_manager()->IterateArchivedThreads(&activations_finder); 8256 isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
8262 has_other_activations = activations_finder.has_activations(); 8257 has_other_activations = activations_finder.has_activations();
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
8432 // Check for optimized activations of this function. 8427 // Check for optimized activations of this function.
8433 JavaScriptFrameIterator it(isolate); 8428 JavaScriptFrameIterator it(isolate);
8434 while (succeeded && !it.done()) { 8429 while (succeeded && !it.done()) {
8435 JavaScriptFrame* frame = it.frame(); 8430 JavaScriptFrame* frame = it.frame();
8436 succeeded = !frame->is_optimized() || frame->function() != *function; 8431 succeeded = !frame->is_optimized() || frame->function() != *function;
8437 it.Advance(); 8432 it.Advance();
8438 } 8433 }
8439 } 8434 }
8440 8435
8441 BailoutId ast_id = BailoutId::None(); 8436 BailoutId ast_id = BailoutId::None();
8437 Handle<Code> osr_code = Handle<Code>::null();
8442 if (succeeded) { 8438 if (succeeded) {
8443 // The top JS function is this one, the PC is somewhere in the 8439 // The top JS function is this one, the PC is somewhere in the
8444 // unoptimized code. 8440 // unoptimized code.
8445 JavaScriptFrameIterator it(isolate); 8441 JavaScriptFrameIterator it(isolate);
8446 JavaScriptFrame* frame = it.frame(); 8442 JavaScriptFrame* frame = it.frame();
8447 ASSERT(frame->function() == *function); 8443 ASSERT(frame->function() == *function);
8448 ASSERT(frame->LookupCode() == *unoptimized); 8444 ASSERT(frame->LookupCode() == *unoptimized);
8449 ASSERT(unoptimized->contains(frame->pc())); 8445 ASSERT(unoptimized->contains(frame->pc()));
8450 8446
8451 // Use linear search of the unoptimized code's back edge table to find 8447 // Use linear search of the unoptimized code's back edge table to find
(...skipping 15 matching lines...) Expand all
8467 table_cursor += FullCodeGenerator::kBackEdgeEntrySize; 8463 table_cursor += FullCodeGenerator::kBackEdgeEntrySize;
8468 } 8464 }
8469 ASSERT(!ast_id.IsNone()); 8465 ASSERT(!ast_id.IsNone());
8470 if (FLAG_trace_osr) { 8466 if (FLAG_trace_osr) {
8471 PrintF("[replacing on-stack at AST id %d, loop depth %d in ", 8467 PrintF("[replacing on-stack at AST id %d, loop depth %d in ",
8472 ast_id.ToInt(), loop_depth); 8468 ast_id.ToInt(), loop_depth);
8473 function->PrintName(); 8469 function->PrintName();
8474 PrintF("]\n"); 8470 PrintF("]\n");
8475 } 8471 }
8476 8472
8477 // Try to compile the optimized code. A true return value from 8473 // Try to compile the function for OSR. A non-null return value indicates
8478 // CompileOptimized means that compilation succeeded, not necessarily 8474 // the compilation succeeded for the given AST id.
8479 // that optimization succeeded. 8475 osr_code = JSFunction::CompileOsr(function, ast_id, CLEAR_EXCEPTION);
8480 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && 8476
8481 function->IsOptimized()) { 8477 if (!osr_code.is_null() &&
8478 osr_code->kind() == Code::OPTIMIZED_FUNCTION) {
8482 DeoptimizationInputData* data = DeoptimizationInputData::cast( 8479 DeoptimizationInputData* data = DeoptimizationInputData::cast(
8483 function->code()->deoptimization_data()); 8480 osr_code->deoptimization_data());
8484 if (data->OsrPcOffset()->value() >= 0) { 8481 if (data->OsrPcOffset()->value() >= 0
8482 && BailoutId(data->OsrAstId()->value()) == ast_id) {
8485 if (FLAG_trace_osr) { 8483 if (FLAG_trace_osr) {
8486 PrintF("[on-stack replacement offset %d in optimized code]\n", 8484 PrintF("[on-stack replacement offset %d in optimized code]\n",
8487 data->OsrPcOffset()->value()); 8485 data->OsrPcOffset()->value());
8488 } 8486 }
8489 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
8490 } else { 8487 } else {
8491 // We may never generate the desired OSR entry if we emit an 8488 // The code we got back did not match our OSR compile request.
8492 // early deoptimize. 8489 osr_code = Handle<Code>::null();
8493 succeeded = false;
8494 } 8490 }
8495 } else { 8491 } else {
8496 succeeded = false; 8492 osr_code = Handle<Code>::null();
8497 } 8493 }
8498 } 8494 }
8499 8495
8500 // Revert to the original interrupt calls in the original unoptimized code. 8496 // Revert to the original interrupt calls in the original unoptimized code.
8501 if (FLAG_trace_osr) { 8497 if (FLAG_trace_osr) {
8502 PrintF("[restoring original interrupt calls in "); 8498 PrintF("[restoring original interrupt calls in ");
8503 function->PrintName(); 8499 function->PrintName();
8504 PrintF("]\n"); 8500 PrintF("]\n");
8505 } 8501 }
8506 InterruptStub interrupt_stub; 8502 InterruptStub interrupt_stub;
8507 Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate); 8503 Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate);
8508 Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement(); 8504 Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement();
8509 Deoptimizer::RevertInterruptCode(*unoptimized, 8505 Deoptimizer::RevertInterruptCode(*unoptimized,
8510 *interrupt_code, 8506 *interrupt_code,
8511 *replacement_code); 8507 *replacement_code);
8512 8508
8513 // If the optimization attempt succeeded, return the AST id tagged as a 8509 // Return the code object to the calling builtin. If non-null, the builtin
8514 // smi. This tells the builtin that we need to translate the unoptimized 8510 // will jump directly to its OSR entrypoint.
8515 // frame to an optimized one. 8511 return osr_code.is_null() ? NULL : *osr_code;
8516 if (succeeded) {
8517 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
8518 return Smi::FromInt(ast_id.ToInt());
8519 } else {
8520 if (function->IsMarkedForLazyRecompilation()) {
8521 function->ReplaceCode(function->shared()->code());
8522 }
8523 return Smi::FromInt(-1);
8524 }
8525 } 8512 }
8526 8513
8527 8514
8528 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) { 8515 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
8529 SealHandleScope shs(isolate); 8516 SealHandleScope shs(isolate);
8530 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); 8517 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
8531 return isolate->heap()->undefined_value(); 8518 return isolate->heap()->undefined_value();
8532 } 8519 }
8533 8520
8534 8521
(...skipping 5323 matching lines...) Expand 10 before | Expand all | Expand 10 after
13858 // Handle last resort GC and make sure to allow future allocations 13845 // Handle last resort GC and make sure to allow future allocations
13859 // to grow the heap without causing GCs (if possible). 13846 // to grow the heap without causing GCs (if possible).
13860 isolate->counters()->gc_last_resort_from_js()->Increment(); 13847 isolate->counters()->gc_last_resort_from_js()->Increment();
13861 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13848 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13862 "Runtime::PerformGC"); 13849 "Runtime::PerformGC");
13863 } 13850 }
13864 } 13851 }
13865 13852
13866 13853
13867 } } // namespace v8::internal 13854 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | src/x64/builtins-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698