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 |