| 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 |