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

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: 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
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 8170 matching lines...) Expand 10 before | Expand all | Expand 10 after
8181 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) { 8181 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
8182 HandleScope scope(isolate); 8182 HandleScope scope(isolate);
8183 ASSERT(args.length() == 1); 8183 ASSERT(args.length() == 1);
8184 Handle<JSFunction> function = args.at<JSFunction>(0); 8184 Handle<JSFunction> function = args.at<JSFunction>(0);
8185 8185
8186 if (!AllowOptimization(isolate, function)) { 8186 if (!AllowOptimization(isolate, function)) {
8187 function->ReplaceCode(function->shared()->code()); 8187 function->ReplaceCode(function->shared()->code());
8188 return function->code(); 8188 return function->code();
8189 } 8189 }
8190 function->shared()->code()->set_profiler_ticks(0); 8190 function->shared()->code()->set_profiler_ticks(0);
8191 if (JSFunction::CompileOptimized(function, 8191 if (JSFunction::CompileOptimized(function, CLEAR_EXCEPTION)) {
8192 BailoutId::None(),
8193 CLEAR_EXCEPTION)) {
8194 return function->code(); 8192 return function->code();
8195 } 8193 }
8196 if (FLAG_trace_opt) { 8194 if (FLAG_trace_opt) {
8197 PrintF("[failed to optimize "); 8195 PrintF("[failed to optimize ");
8198 function->PrintName(); 8196 function->PrintName();
8199 PrintF(": optimized compilation failed]\n"); 8197 PrintF(": optimized compilation failed]\n");
8200 } 8198 }
8201 function->ReplaceCode(function->shared()->code()); 8199 function->ReplaceCode(function->shared()->code());
8202 return function->code(); 8200 return function->code();
8203 } 8201 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
8276 8274
8277 // Make sure to materialize objects before causing any allocation. 8275 // Make sure to materialize objects before causing any allocation.
8278 JavaScriptFrameIterator it(isolate); 8276 JavaScriptFrameIterator it(isolate);
8279 deoptimizer->MaterializeHeapObjects(&it); 8277 deoptimizer->MaterializeHeapObjects(&it);
8280 delete deoptimizer; 8278 delete deoptimizer;
8281 8279
8282 JavaScriptFrame* frame = it.frame(); 8280 JavaScriptFrame* frame = it.frame();
8283 RUNTIME_ASSERT(frame->function()->IsJSFunction()); 8281 RUNTIME_ASSERT(frame->function()->IsJSFunction());
8284 Handle<JSFunction> function(frame->function(), isolate); 8282 Handle<JSFunction> function(frame->function(), isolate);
8285 Handle<Code> optimized_code(function->code()); 8283 Handle<Code> optimized_code(function->code());
8286 RUNTIME_ASSERT((type != Deoptimizer::EAGER &&
8287 type != Deoptimizer::SOFT) || function->IsOptimized());
8288 8284
8289 // Avoid doing too much work when running with --always-opt and keep 8285 // Avoid doing too much work when running with --always-opt and keep
8290 // the optimized code around. 8286 // the optimized code around.
8291 if (FLAG_always_opt || type == Deoptimizer::LAZY) { 8287 if (FLAG_always_opt || type == Deoptimizer::LAZY) {
8292 return isolate->heap()->undefined_value(); 8288 return isolate->heap()->undefined_value();
8293 } 8289 }
8294 8290
8295 // Find other optimized activations of the function or functions that 8291 // Find other optimized activations of the function or functions that
8296 // share the same optimized code. 8292 // share the same optimized code.
8297 bool has_other_activations = false; 8293 bool has_other_activations = false;
Michael Starzinger 2013/07/31 14:55:50 We should only look for activations of optimized c
Michael Starzinger 2013/07/31 16:29:33 As discussed offline: Yes, your are right, if func
8298 while (!it.done()) { 8294 while (!it.done()) {
8299 JavaScriptFrame* frame = it.frame(); 8295 JavaScriptFrame* frame = it.frame();
8300 JSFunction* other_function = frame->function(); 8296 JSFunction* other_function = frame->function();
8301 if (frame->is_optimized() && other_function->code() == function->code()) { 8297 if (frame->is_optimized() && other_function->code() == function->code()) {
8302 has_other_activations = true; 8298 has_other_activations = true;
8303 break; 8299 break;
8304 } 8300 }
8305 it.Advance(); 8301 it.Advance();
8306 } 8302 }
8307 8303
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
8481 // Check for optimized activations of this function. 8477 // Check for optimized activations of this function.
8482 JavaScriptFrameIterator it(isolate); 8478 JavaScriptFrameIterator it(isolate);
8483 while (succeeded && !it.done()) { 8479 while (succeeded && !it.done()) {
8484 JavaScriptFrame* frame = it.frame(); 8480 JavaScriptFrame* frame = it.frame();
8485 succeeded = !frame->is_optimized() || frame->function() != *function; 8481 succeeded = !frame->is_optimized() || frame->function() != *function;
8486 it.Advance(); 8482 it.Advance();
8487 } 8483 }
8488 } 8484 }
8489 8485
8490 BailoutId ast_id = BailoutId::None(); 8486 BailoutId ast_id = BailoutId::None();
8487 Handle<Code> osr_code = Handle<Code>::null();
8491 if (succeeded) { 8488 if (succeeded) {
8492 // The top JS function is this one, the PC is somewhere in the 8489 // The top JS function is this one, the PC is somewhere in the
8493 // unoptimized code. 8490 // unoptimized code.
8494 JavaScriptFrameIterator it(isolate); 8491 JavaScriptFrameIterator it(isolate);
8495 JavaScriptFrame* frame = it.frame(); 8492 JavaScriptFrame* frame = it.frame();
8496 ASSERT(frame->function() == *function); 8493 ASSERT(frame->function() == *function);
8497 ASSERT(frame->LookupCode() == *unoptimized); 8494 ASSERT(frame->LookupCode() == *unoptimized);
8498 ASSERT(unoptimized->contains(frame->pc())); 8495 ASSERT(unoptimized->contains(frame->pc()));
8499 8496
8500 // Use linear search of the unoptimized code's back edge table to find 8497 // Use linear search of the unoptimized code's back edge table to find
(...skipping 15 matching lines...) Expand all
8516 table_cursor += FullCodeGenerator::kBackEdgeEntrySize; 8513 table_cursor += FullCodeGenerator::kBackEdgeEntrySize;
8517 } 8514 }
8518 ASSERT(!ast_id.IsNone()); 8515 ASSERT(!ast_id.IsNone());
8519 if (FLAG_trace_osr) { 8516 if (FLAG_trace_osr) {
8520 PrintF("[replacing on-stack at AST id %d, loop depth %d in ", 8517 PrintF("[replacing on-stack at AST id %d, loop depth %d in ",
8521 ast_id.ToInt(), loop_depth); 8518 ast_id.ToInt(), loop_depth);
8522 function->PrintName(); 8519 function->PrintName();
8523 PrintF("]\n"); 8520 PrintF("]\n");
8524 } 8521 }
8525 8522
8526 // Try to compile the optimized code. A true return value from 8523 // Try to compile the function for OSR. A non-null return value indicates
8527 // CompileOptimized means that compilation succeeded, not necessarily 8524 // the compilation succeeded for the given AST id.
8528 // that optimization succeeded. 8525 osr_code = JSFunction::CompileOsr(function, ast_id, CLEAR_EXCEPTION);
8529 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && 8526
8530 function->IsOptimized()) { 8527 if (!osr_code.is_null() &&
8528 osr_code->kind() == Code::OPTIMIZED_FUNCTION) {
8531 DeoptimizationInputData* data = DeoptimizationInputData::cast( 8529 DeoptimizationInputData* data = DeoptimizationInputData::cast(
8532 function->code()->deoptimization_data()); 8530 osr_code->deoptimization_data());
8533 if (data->OsrPcOffset()->value() >= 0) { 8531 if (data->OsrPcOffset()->value() >= 0
8532 && BailoutId(data->OsrAstId()->value()) == ast_id) {
8534 if (FLAG_trace_osr) { 8533 if (FLAG_trace_osr) {
8535 PrintF("[on-stack replacement offset %d in optimized code]\n", 8534 PrintF("[on-stack replacement offset %d in optimized code]\n",
8536 data->OsrPcOffset()->value()); 8535 data->OsrPcOffset()->value());
8537 } 8536 }
8538 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
8539 } else { 8537 } else {
8540 // We may never generate the desired OSR entry if we emit an 8538 // The code we got back did not match our OSR compile request.
8541 // early deoptimize. 8539 osr_code = Handle<Code>::null();
8542 succeeded = false;
8543 } 8540 }
8544 } else { 8541 } else {
8545 succeeded = false; 8542 osr_code = Handle<Code>::null();
8546 } 8543 }
8547 } 8544 }
8548 8545
8549 // Revert to the original interrupt calls in the original unoptimized code. 8546 // Revert to the original interrupt calls in the original unoptimized code.
8550 if (FLAG_trace_osr) { 8547 if (FLAG_trace_osr) {
8551 PrintF("[restoring original interrupt calls in "); 8548 PrintF("[restoring original interrupt calls in ");
8552 function->PrintName(); 8549 function->PrintName();
8553 PrintF("]\n"); 8550 PrintF("]\n");
8554 } 8551 }
8555 InterruptStub interrupt_stub; 8552 InterruptStub interrupt_stub;
8556 Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate); 8553 Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate);
8557 Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement(); 8554 Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement();
8558 Deoptimizer::RevertInterruptCode(*unoptimized, 8555 Deoptimizer::RevertInterruptCode(*unoptimized,
8559 *interrupt_code, 8556 *interrupt_code,
8560 *replacement_code); 8557 *replacement_code);
8561 8558
8562 // If the optimization attempt succeeded, return the AST id tagged as a 8559 // Return the code object to the calling builtin. If non-null, the builtin
8563 // smi. This tells the builtin that we need to translate the unoptimized 8560 // will jump directly to its OSR entrypoint.
8564 // frame to an optimized one. 8561 return osr_code.is_null() ? NULL: *osr_code;
Michael Starzinger 2013/07/31 14:55:50 nit: Missing white-space in front of the colon.
8565 if (succeeded) {
8566 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
8567 return Smi::FromInt(ast_id.ToInt());
8568 } else {
8569 if (function->IsMarkedForLazyRecompilation()) {
8570 function->ReplaceCode(function->shared()->code());
8571 }
8572 return Smi::FromInt(-1);
8573 }
8574 } 8562 }
8575 8563
8576 8564
8577 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) { 8565 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
8578 SealHandleScope shs(isolate); 8566 SealHandleScope shs(isolate);
8579 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); 8567 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
8580 return isolate->heap()->undefined_value(); 8568 return isolate->heap()->undefined_value();
8581 } 8569 }
8582 8570
8583 8571
(...skipping 5323 matching lines...) Expand 10 before | Expand all | Expand 10 after
13907 // Handle last resort GC and make sure to allow future allocations 13895 // Handle last resort GC and make sure to allow future allocations
13908 // to grow the heap without causing GCs (if possible). 13896 // to grow the heap without causing GCs (if possible).
13909 isolate->counters()->gc_last_resort_from_js()->Increment(); 13897 isolate->counters()->gc_last_resort_from_js()->Increment();
13910 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13898 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13911 "Runtime::PerformGC"); 13899 "Runtime::PerformGC");
13912 } 13900 }
13913 } 13901 }
13914 13902
13915 13903
13916 } } // namespace v8::internal 13904 } } // namespace v8::internal
OLDNEW
« src/objects.cc ('K') | « src/objects.cc ('k') | src/x64/builtins-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698