| 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 7888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7899 function->PrintName(); | 7899 function->PrintName(); |
| 7900 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", | 7900 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", |
| 7901 function->shared()->code()->optimizable() ? "T" : "F", | 7901 function->shared()->code()->optimizable() ? "T" : "F", |
| 7902 isolate->DebuggerHasBreakPoints() ? "T" : "F"); | 7902 isolate->DebuggerHasBreakPoints() ? "T" : "F"); |
| 7903 } | 7903 } |
| 7904 function->ReplaceCode(function->shared()->code()); | 7904 function->ReplaceCode(function->shared()->code()); |
| 7905 return function->code(); | 7905 return function->code(); |
| 7906 } | 7906 } |
| 7907 function->shared()->code()->set_profiler_ticks(0); | 7907 function->shared()->code()->set_profiler_ticks(0); |
| 7908 if (JSFunction::CompileOptimized(function, | 7908 if (JSFunction::CompileOptimized(function, |
| 7909 AstNode::kNoNumber, | 7909 BailoutId::None(), |
| 7910 CLEAR_EXCEPTION)) { | 7910 CLEAR_EXCEPTION)) { |
| 7911 return function->code(); | 7911 return function->code(); |
| 7912 } | 7912 } |
| 7913 if (FLAG_trace_opt) { | 7913 if (FLAG_trace_opt) { |
| 7914 PrintF("[failed to optimize "); | 7914 PrintF("[failed to optimize "); |
| 7915 function->PrintName(); | 7915 function->PrintName(); |
| 7916 PrintF(": optimized compilation failed]\n"); | 7916 PrintF(": optimized compilation failed]\n"); |
| 7917 } | 7917 } |
| 7918 function->ReplaceCode(function->shared()->code()); | 7918 function->ReplaceCode(function->shared()->code()); |
| 7919 return function->code(); | 7919 return function->code(); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8166 // deoptimized so that we are currently in an unoptimized activation. | 8166 // deoptimized so that we are currently in an unoptimized activation. |
| 8167 // Check for optimized activations of this function. | 8167 // Check for optimized activations of this function. |
| 8168 JavaScriptFrameIterator it(isolate); | 8168 JavaScriptFrameIterator it(isolate); |
| 8169 while (succeeded && !it.done()) { | 8169 while (succeeded && !it.done()) { |
| 8170 JavaScriptFrame* frame = it.frame(); | 8170 JavaScriptFrame* frame = it.frame(); |
| 8171 succeeded = !frame->is_optimized() || frame->function() != *function; | 8171 succeeded = !frame->is_optimized() || frame->function() != *function; |
| 8172 it.Advance(); | 8172 it.Advance(); |
| 8173 } | 8173 } |
| 8174 } | 8174 } |
| 8175 | 8175 |
| 8176 int ast_id = AstNode::kNoNumber; | 8176 BailoutId ast_id = BailoutId::None(); |
| 8177 if (succeeded) { | 8177 if (succeeded) { |
| 8178 // The top JS function is this one, the PC is somewhere in the | 8178 // The top JS function is this one, the PC is somewhere in the |
| 8179 // unoptimized code. | 8179 // unoptimized code. |
| 8180 JavaScriptFrameIterator it(isolate); | 8180 JavaScriptFrameIterator it(isolate); |
| 8181 JavaScriptFrame* frame = it.frame(); | 8181 JavaScriptFrame* frame = it.frame(); |
| 8182 ASSERT(frame->function() == *function); | 8182 ASSERT(frame->function() == *function); |
| 8183 ASSERT(frame->LookupCode() == *unoptimized); | 8183 ASSERT(frame->LookupCode() == *unoptimized); |
| 8184 ASSERT(unoptimized->contains(frame->pc())); | 8184 ASSERT(unoptimized->contains(frame->pc())); |
| 8185 | 8185 |
| 8186 // Use linear search of the unoptimized code's stack check table to find | 8186 // Use linear search of the unoptimized code's stack check table to find |
| 8187 // the AST id matching the PC. | 8187 // the AST id matching the PC. |
| 8188 Address start = unoptimized->instruction_start(); | 8188 Address start = unoptimized->instruction_start(); |
| 8189 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); | 8189 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); |
| 8190 Address table_cursor = start + unoptimized->stack_check_table_offset(); | 8190 Address table_cursor = start + unoptimized->stack_check_table_offset(); |
| 8191 uint32_t table_length = Memory::uint32_at(table_cursor); | 8191 uint32_t table_length = Memory::uint32_at(table_cursor); |
| 8192 table_cursor += kIntSize; | 8192 table_cursor += kIntSize; |
| 8193 for (unsigned i = 0; i < table_length; ++i) { | 8193 for (unsigned i = 0; i < table_length; ++i) { |
| 8194 // Table entries are (AST id, pc offset) pairs. | 8194 // Table entries are (AST id, pc offset) pairs. |
| 8195 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize); | 8195 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize); |
| 8196 if (pc_offset == target_pc_offset) { | 8196 if (pc_offset == target_pc_offset) { |
| 8197 ast_id = static_cast<int>(Memory::uint32_at(table_cursor)); | 8197 ast_id = BailoutId(static_cast<int>(Memory::uint32_at(table_cursor))); |
| 8198 break; | 8198 break; |
| 8199 } | 8199 } |
| 8200 table_cursor += 2 * kIntSize; | 8200 table_cursor += 2 * kIntSize; |
| 8201 } | 8201 } |
| 8202 ASSERT(ast_id != AstNode::kNoNumber); | 8202 ASSERT(!ast_id.IsNone()); |
| 8203 if (FLAG_trace_osr) { | 8203 if (FLAG_trace_osr) { |
| 8204 PrintF("[replacing on-stack at AST id %d in ", ast_id); | 8204 PrintF("[replacing on-stack at AST id %d in ", ast_id.ToInt()); |
| 8205 function->PrintName(); | 8205 function->PrintName(); |
| 8206 PrintF("]\n"); | 8206 PrintF("]\n"); |
| 8207 } | 8207 } |
| 8208 | 8208 |
| 8209 // Try to compile the optimized code. A true return value from | 8209 // Try to compile the optimized code. A true return value from |
| 8210 // CompileOptimized means that compilation succeeded, not necessarily | 8210 // CompileOptimized means that compilation succeeded, not necessarily |
| 8211 // that optimization succeeded. | 8211 // that optimization succeeded. |
| 8212 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && | 8212 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && |
| 8213 function->IsOptimized()) { | 8213 function->IsOptimized()) { |
| 8214 DeoptimizationInputData* data = DeoptimizationInputData::cast( | 8214 DeoptimizationInputData* data = DeoptimizationInputData::cast( |
| 8215 function->code()->deoptimization_data()); | 8215 function->code()->deoptimization_data()); |
| 8216 if (data->OsrPcOffset()->value() >= 0) { | 8216 if (data->OsrPcOffset()->value() >= 0) { |
| 8217 if (FLAG_trace_osr) { | 8217 if (FLAG_trace_osr) { |
| 8218 PrintF("[on-stack replacement offset %d in optimized code]\n", | 8218 PrintF("[on-stack replacement offset %d in optimized code]\n", |
| 8219 data->OsrPcOffset()->value()); | 8219 data->OsrPcOffset()->value()); |
| 8220 } | 8220 } |
| 8221 ASSERT(data->OsrAstId()->value() == ast_id); | 8221 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id); |
| 8222 } else { | 8222 } else { |
| 8223 // We may never generate the desired OSR entry if we emit an | 8223 // We may never generate the desired OSR entry if we emit an |
| 8224 // early deoptimize. | 8224 // early deoptimize. |
| 8225 succeeded = false; | 8225 succeeded = false; |
| 8226 } | 8226 } |
| 8227 } else { | 8227 } else { |
| 8228 succeeded = false; | 8228 succeeded = false; |
| 8229 } | 8229 } |
| 8230 } | 8230 } |
| 8231 | 8231 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 8250 *replacement_code); | 8250 *replacement_code); |
| 8251 | 8251 |
| 8252 // Allow OSR only at nesting level zero again. | 8252 // Allow OSR only at nesting level zero again. |
| 8253 unoptimized->set_allow_osr_at_loop_nesting_level(0); | 8253 unoptimized->set_allow_osr_at_loop_nesting_level(0); |
| 8254 | 8254 |
| 8255 // If the optimization attempt succeeded, return the AST id tagged as a | 8255 // If the optimization attempt succeeded, return the AST id tagged as a |
| 8256 // smi. This tells the builtin that we need to translate the unoptimized | 8256 // smi. This tells the builtin that we need to translate the unoptimized |
| 8257 // frame to an optimized one. | 8257 // frame to an optimized one. |
| 8258 if (succeeded) { | 8258 if (succeeded) { |
| 8259 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); | 8259 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); |
| 8260 return Smi::FromInt(ast_id); | 8260 return Smi::FromInt(ast_id.ToInt()); |
| 8261 } else { | 8261 } else { |
| 8262 if (function->IsMarkedForLazyRecompilation()) { | 8262 if (function->IsMarkedForLazyRecompilation()) { |
| 8263 function->ReplaceCode(function->shared()->code()); | 8263 function->ReplaceCode(function->shared()->code()); |
| 8264 } | 8264 } |
| 8265 return Smi::FromInt(-1); | 8265 return Smi::FromInt(-1); |
| 8266 } | 8266 } |
| 8267 } | 8267 } |
| 8268 | 8268 |
| 8269 | 8269 |
| 8270 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) { | 8270 RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) { |
| (...skipping 5075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13346 // Handle last resort GC and make sure to allow future allocations | 13346 // Handle last resort GC and make sure to allow future allocations |
| 13347 // to grow the heap without causing GCs (if possible). | 13347 // to grow the heap without causing GCs (if possible). |
| 13348 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13348 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13349 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13349 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13350 "Runtime::PerformGC"); | 13350 "Runtime::PerformGC"); |
| 13351 } | 13351 } |
| 13352 } | 13352 } |
| 13353 | 13353 |
| 13354 | 13354 |
| 13355 } } // namespace v8::internal | 13355 } } // namespace v8::internal |
| OLD | NEW |