OLD | NEW |
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 8257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8268 function->PrintName(); | 8268 function->PrintName(); |
8269 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", | 8269 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", |
8270 function->shared()->code()->optimizable() ? "T" : "F", | 8270 function->shared()->code()->optimizable() ? "T" : "F", |
8271 isolate->DebuggerHasBreakPoints() ? "T" : "F"); | 8271 isolate->DebuggerHasBreakPoints() ? "T" : "F"); |
8272 } | 8272 } |
8273 function->ReplaceCode(function->shared()->code()); | 8273 function->ReplaceCode(function->shared()->code()); |
8274 return function->code(); | 8274 return function->code(); |
8275 } | 8275 } |
8276 function->shared()->code()->set_profiler_ticks(0); | 8276 function->shared()->code()->set_profiler_ticks(0); |
8277 if (JSFunction::CompileOptimized(function, | 8277 if (JSFunction::CompileOptimized(function, |
8278 AstNode::kNoNumber, | 8278 BailoutId::None(), |
8279 CLEAR_EXCEPTION)) { | 8279 CLEAR_EXCEPTION)) { |
8280 return function->code(); | 8280 return function->code(); |
8281 } | 8281 } |
8282 if (FLAG_trace_opt) { | 8282 if (FLAG_trace_opt) { |
8283 PrintF("[failed to optimize "); | 8283 PrintF("[failed to optimize "); |
8284 function->PrintName(); | 8284 function->PrintName(); |
8285 PrintF(": optimized compilation failed]\n"); | 8285 PrintF(": optimized compilation failed]\n"); |
8286 } | 8286 } |
8287 function->ReplaceCode(function->shared()->code()); | 8287 function->ReplaceCode(function->shared()->code()); |
8288 return function->code(); | 8288 return function->code(); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8535 // deoptimized so that we are currently in an unoptimized activation. | 8535 // deoptimized so that we are currently in an unoptimized activation. |
8536 // Check for optimized activations of this function. | 8536 // Check for optimized activations of this function. |
8537 JavaScriptFrameIterator it(isolate); | 8537 JavaScriptFrameIterator it(isolate); |
8538 while (succeeded && !it.done()) { | 8538 while (succeeded && !it.done()) { |
8539 JavaScriptFrame* frame = it.frame(); | 8539 JavaScriptFrame* frame = it.frame(); |
8540 succeeded = !frame->is_optimized() || frame->function() != *function; | 8540 succeeded = !frame->is_optimized() || frame->function() != *function; |
8541 it.Advance(); | 8541 it.Advance(); |
8542 } | 8542 } |
8543 } | 8543 } |
8544 | 8544 |
8545 int ast_id = AstNode::kNoNumber; | 8545 BailoutId ast_id = BailoutId::None(); |
8546 if (succeeded) { | 8546 if (succeeded) { |
8547 // The top JS function is this one, the PC is somewhere in the | 8547 // The top JS function is this one, the PC is somewhere in the |
8548 // unoptimized code. | 8548 // unoptimized code. |
8549 JavaScriptFrameIterator it(isolate); | 8549 JavaScriptFrameIterator it(isolate); |
8550 JavaScriptFrame* frame = it.frame(); | 8550 JavaScriptFrame* frame = it.frame(); |
8551 ASSERT(frame->function() == *function); | 8551 ASSERT(frame->function() == *function); |
8552 ASSERT(frame->LookupCode() == *unoptimized); | 8552 ASSERT(frame->LookupCode() == *unoptimized); |
8553 ASSERT(unoptimized->contains(frame->pc())); | 8553 ASSERT(unoptimized->contains(frame->pc())); |
8554 | 8554 |
8555 // Use linear search of the unoptimized code's stack check table to find | 8555 // Use linear search of the unoptimized code's stack check table to find |
8556 // the AST id matching the PC. | 8556 // the AST id matching the PC. |
8557 Address start = unoptimized->instruction_start(); | 8557 Address start = unoptimized->instruction_start(); |
8558 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); | 8558 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); |
8559 Address table_cursor = start + unoptimized->stack_check_table_offset(); | 8559 Address table_cursor = start + unoptimized->stack_check_table_offset(); |
8560 uint32_t table_length = Memory::uint32_at(table_cursor); | 8560 uint32_t table_length = Memory::uint32_at(table_cursor); |
8561 table_cursor += kIntSize; | 8561 table_cursor += kIntSize; |
8562 for (unsigned i = 0; i < table_length; ++i) { | 8562 for (unsigned i = 0; i < table_length; ++i) { |
8563 // Table entries are (AST id, pc offset) pairs. | 8563 // Table entries are (AST id, pc offset) pairs. |
8564 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize); | 8564 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize); |
8565 if (pc_offset == target_pc_offset) { | 8565 if (pc_offset == target_pc_offset) { |
8566 ast_id = static_cast<int>(Memory::uint32_at(table_cursor)); | 8566 ast_id = BailoutId(static_cast<int>(Memory::uint32_at(table_cursor))); |
8567 break; | 8567 break; |
8568 } | 8568 } |
8569 table_cursor += 2 * kIntSize; | 8569 table_cursor += 2 * kIntSize; |
8570 } | 8570 } |
8571 ASSERT(ast_id != AstNode::kNoNumber); | 8571 ASSERT(!ast_id.IsNone()); |
8572 if (FLAG_trace_osr) { | 8572 if (FLAG_trace_osr) { |
8573 PrintF("[replacing on-stack at AST id %d in ", ast_id); | 8573 PrintF("[replacing on-stack at AST id %d in ", ast_id.ToInt()); |
8574 function->PrintName(); | 8574 function->PrintName(); |
8575 PrintF("]\n"); | 8575 PrintF("]\n"); |
8576 } | 8576 } |
8577 | 8577 |
8578 // Try to compile the optimized code. A true return value from | 8578 // Try to compile the optimized code. A true return value from |
8579 // CompileOptimized means that compilation succeeded, not necessarily | 8579 // CompileOptimized means that compilation succeeded, not necessarily |
8580 // that optimization succeeded. | 8580 // that optimization succeeded. |
8581 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && | 8581 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && |
8582 function->IsOptimized()) { | 8582 function->IsOptimized()) { |
8583 DeoptimizationInputData* data = DeoptimizationInputData::cast( | 8583 DeoptimizationInputData* data = DeoptimizationInputData::cast( |
8584 function->code()->deoptimization_data()); | 8584 function->code()->deoptimization_data()); |
8585 if (data->OsrPcOffset()->value() >= 0) { | 8585 if (data->OsrPcOffset()->value() >= 0) { |
8586 if (FLAG_trace_osr) { | 8586 if (FLAG_trace_osr) { |
8587 PrintF("[on-stack replacement offset %d in optimized code]\n", | 8587 PrintF("[on-stack replacement offset %d in optimized code]\n", |
8588 data->OsrPcOffset()->value()); | 8588 data->OsrPcOffset()->value()); |
8589 } | 8589 } |
8590 ASSERT(data->OsrAstId()->value() == ast_id); | 8590 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id); |
8591 } else { | 8591 } else { |
8592 // We may never generate the desired OSR entry if we emit an | 8592 // We may never generate the desired OSR entry if we emit an |
8593 // early deoptimize. | 8593 // early deoptimize. |
8594 succeeded = false; | 8594 succeeded = false; |
8595 } | 8595 } |
8596 } else { | 8596 } else { |
8597 succeeded = false; | 8597 succeeded = false; |
8598 } | 8598 } |
8599 } | 8599 } |
8600 | 8600 |
(...skipping 18 matching lines...) Expand all Loading... |
8619 *replacement_code); | 8619 *replacement_code); |
8620 | 8620 |
8621 // Allow OSR only at nesting level zero again. | 8621 // Allow OSR only at nesting level zero again. |
8622 unoptimized->set_allow_osr_at_loop_nesting_level(0); | 8622 unoptimized->set_allow_osr_at_loop_nesting_level(0); |
8623 | 8623 |
8624 // If the optimization attempt succeeded, return the AST id tagged as a | 8624 // If the optimization attempt succeeded, return the AST id tagged as a |
8625 // smi. This tells the builtin that we need to translate the unoptimized | 8625 // smi. This tells the builtin that we need to translate the unoptimized |
8626 // frame to an optimized one. | 8626 // frame to an optimized one. |
8627 if (succeeded) { | 8627 if (succeeded) { |
8628 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); | 8628 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); |
8629 return Smi::FromInt(ast_id); | 8629 return Smi::FromInt(ast_id.ToInt()); |
8630 } else { | 8630 } else { |
8631 if (function->IsMarkedForLazyRecompilation()) { | 8631 if (function->IsMarkedForLazyRecompilation()) { |
8632 function->ReplaceCode(function->shared()->code()); | 8632 function->ReplaceCode(function->shared()->code()); |
8633 } | 8633 } |
8634 return Smi::FromInt(-1); | 8634 return Smi::FromInt(-1); |
8635 } | 8635 } |
8636 } | 8636 } |
8637 | 8637 |
8638 | 8638 |
8639 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) { | 8639 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) { |
(...skipping 5075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13715 // Handle last resort GC and make sure to allow future allocations | 13715 // Handle last resort GC and make sure to allow future allocations |
13716 // to grow the heap without causing GCs (if possible). | 13716 // to grow the heap without causing GCs (if possible). |
13717 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13717 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13718 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13718 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13719 "Runtime::PerformGC"); | 13719 "Runtime::PerformGC"); |
13720 } | 13720 } |
13721 } | 13721 } |
13722 | 13722 |
13723 | 13723 |
13724 } } // namespace v8::internal | 13724 } } // namespace v8::internal |
OLD | NEW |