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 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1111 InstallFullCode(*info); | 1111 InstallFullCode(*info); |
1112 } | 1112 } |
1113 // Optimized code is finally replacing unoptimized code. Reset the latter's | 1113 // Optimized code is finally replacing unoptimized code. Reset the latter's |
1114 // profiler ticks to prevent too soon re-opt after a deopt. | 1114 // profiler ticks to prevent too soon re-opt after a deopt. |
1115 info->shared_info()->code()->set_profiler_ticks(0); | 1115 info->shared_info()->code()->set_profiler_ticks(0); |
1116 ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode()); | 1116 ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode()); |
1117 return status == OptimizingCompiler::SUCCEEDED; | 1117 return status == OptimizingCompiler::SUCCEEDED; |
1118 } | 1118 } |
1119 | 1119 |
1120 | 1120 |
1121 static uint32_t CurrentPcOffset(Isolate* isolate, | |
1122 Handle<JSFunction> function, | |
1123 Handle<Code> unoptimized) { | |
1124 JavaScriptFrameIterator it(isolate); | |
1125 JavaScriptFrame* frame = it.frame(); | |
1126 ASSERT(frame->function() == *function); | |
1127 ASSERT(frame->LookupCode() == *unoptimized); | |
1128 ASSERT(unoptimized->contains(frame->pc())); | |
1129 | |
1130 // Use linear search of the unoptimized code's back edge table to find | |
1131 // the AST id matching the PC. | |
1132 return static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start()); | |
1133 } | |
1134 | |
1135 | |
1136 static bool IsSuitableForOnStackReplacement(Isolate* isolate, | 1121 static bool IsSuitableForOnStackReplacement(Isolate* isolate, |
1137 Handle<JSFunction> function, | 1122 Handle<JSFunction> function, |
1138 Handle<Code> unoptimized) { | 1123 Handle<Code> unoptimized) { |
1139 // Keep track of whether we've succeeded in optimizing. | 1124 // Keep track of whether we've succeeded in optimizing. |
1140 if (!unoptimized->optimizable()) return false; | 1125 if (!unoptimized->optimizable()) return false; |
1141 // If we are trying to do OSR when there are already optimized | 1126 // If we are trying to do OSR when there are already optimized |
1142 // activations of the function, it means (a) the function is directly or | 1127 // activations of the function, it means (a) the function is directly or |
1143 // indirectly recursive and (b) an optimized invocation has been | 1128 // indirectly recursive and (b) an optimized invocation has been |
1144 // deoptimized so that we are currently in an unoptimized activation. | 1129 // deoptimized so that we are currently in an unoptimized activation. |
1145 // Check for optimized activations of this function. | 1130 // Check for optimized activations of this function. |
1146 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { | 1131 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { |
1147 JavaScriptFrame* frame = it.frame(); | 1132 JavaScriptFrame* frame = it.frame(); |
1148 if (frame->is_optimized() && frame->function() == *function) return false; | 1133 if (frame->is_optimized() && frame->function() == *function) return false; |
1149 } | 1134 } |
1150 | 1135 |
1151 return true; | 1136 return true; |
1152 } | 1137 } |
1153 | 1138 |
1154 | 1139 |
1155 Handle<Code> Compiler::CompileForOnStackReplacement( | 1140 Handle<Code> Compiler::CompileForOnStackReplacement( |
1156 Handle<JSFunction> function) { | 1141 Handle<JSFunction> function, uint32_t pc_offset) { |
1157 Isolate* isolate = function->GetIsolate(); | 1142 Isolate* isolate = function->GetIsolate(); |
1158 Handle<Code> unoptimized(function->shared()->code(), isolate); | 1143 Handle<Code> unoptimized(function->shared()->code(), isolate); |
1159 | 1144 |
1160 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); | 1145 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); |
titzer
2013/09/10 11:00:46
Please move this reversion of the interrupt code b
| |
1161 if (FLAG_trace_osr) { | 1146 if (FLAG_trace_osr) { |
1162 PrintF("[OSR - restored original interrupt calls in "); | 1147 PrintF("[OSR - restored original interrupt calls in "); |
1163 function->PrintName(); | 1148 function->PrintName(); |
1164 PrintF("]\n"); | 1149 PrintF("]\n"); |
1165 } | 1150 } |
1166 | 1151 |
1167 if (IsSuitableForOnStackReplacement(isolate, function, unoptimized)) { | 1152 if (IsSuitableForOnStackReplacement(isolate, function, unoptimized)) { |
titzer
2013/09/10 11:00:46
And this as well. The compiler should just compile
| |
1168 // Find the PC offset in unoptimized code and translate to an AST id. | 1153 // Find the PC offset in unoptimized code and translate to an AST id. |
1169 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized); | |
1170 BailoutId ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset); | 1154 BailoutId ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset); |
1171 ASSERT(!ast_id.IsNone()); | 1155 ASSERT(!ast_id.IsNone()); |
1172 if (FLAG_trace_osr) { | 1156 if (FLAG_trace_osr) { |
1173 PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt()); | 1157 PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt()); |
1174 function->PrintName(); | 1158 function->PrintName(); |
1175 PrintF("]\n"); | 1159 PrintF("]\n"); |
1176 } | 1160 } |
1177 | 1161 |
1178 // Attempt OSR compilation. | 1162 // Attempt OSR compilation. |
1179 Handle<Code> result = JSFunction::CompileOsr( | 1163 Handle<Code> result = JSFunction::CompileOsr( |
(...skipping 14 matching lines...) Expand all Loading... | |
1194 | 1178 |
1195 if (FLAG_trace_osr) { | 1179 if (FLAG_trace_osr) { |
1196 PrintF("[OSR - attempt failed for "); | 1180 PrintF("[OSR - attempt failed for "); |
1197 function->PrintName(); | 1181 function->PrintName(); |
1198 PrintF("]\n"); | 1182 PrintF("]\n"); |
1199 } | 1183 } |
1200 return Handle<Code>::null(); | 1184 return Handle<Code>::null(); |
1201 } | 1185 } |
1202 | 1186 |
1203 | 1187 |
1204 Handle<Code> Compiler::CompileForConcurrentOSR(Handle<JSFunction> function) { | 1188 Handle<Code> Compiler::CompileForConcurrentOSR(Handle<JSFunction> function, |
1189 uint32_t pc_offset) { | |
1205 Isolate* isolate = function->GetIsolate(); | 1190 Isolate* isolate = function->GetIsolate(); |
1206 Handle<Code> unoptimized(function->shared()->code(), isolate); | |
1207 | |
1208 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized); | |
1209 | 1191 |
1210 if (isolate->optimizing_compiler_thread()-> | 1192 if (isolate->optimizing_compiler_thread()-> |
1211 IsQueuedForOSR(function, pc_offset)) { | 1193 IsQueuedForOSR(function, pc_offset)) { |
1212 // Still waiting for the optimizing compiler thread to finish. Carry on. | 1194 // Still waiting for the optimizing compiler thread to finish. Carry on. |
1213 if (FLAG_trace_osr) { | 1195 if (FLAG_trace_osr) { |
1214 PrintF("[COSR - polling recompile tasks for "); | 1196 PrintF("[COSR - polling recompile tasks for "); |
1215 function->PrintName(); | 1197 function->PrintName(); |
1216 PrintF("]\n"); | 1198 PrintF("]\n"); |
1217 } | 1199 } |
1218 return Handle<Code>::null(); | 1200 return Handle<Code>::null(); |
1219 } | 1201 } |
1220 | 1202 |
1203 Handle<Code> unoptimized(function->shared()->code(), isolate); | |
1221 OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()-> | 1204 OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()-> |
1222 FindReadyOSRCandidate(function, pc_offset); | 1205 FindReadyOSRCandidate(function, pc_offset); |
1223 | 1206 |
1224 if (compiler != NULL) { | 1207 if (compiler != NULL) { |
1225 if (FLAG_trace_osr) { | 1208 if (FLAG_trace_osr) { |
1226 PrintF("[COSR - optimization complete for "); | 1209 PrintF("[COSR - optimization complete for "); |
1227 function->PrintName(); | 1210 function->PrintName(); |
1228 PrintF(", restoring interrupt calls]\n"); | 1211 PrintF(", restoring interrupt calls]\n"); |
1229 } | 1212 } |
1230 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); | 1213 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); |
(...skipping 24 matching lines...) Expand all Loading... | |
1255 if (FLAG_trace_osr) { | 1238 if (FLAG_trace_osr) { |
1256 PrintF("[COSR - entry at AST id %d, offset %d in optimized code]\n", | 1239 PrintF("[COSR - entry at AST id %d, offset %d in optimized code]\n", |
1257 ast_id.ToInt(), data->OsrPcOffset()->value()); | 1240 ast_id.ToInt(), data->OsrPcOffset()->value()); |
1258 } | 1241 } |
1259 return result; | 1242 return result; |
1260 } | 1243 } |
1261 } | 1244 } |
1262 return Handle<Code>::null(); | 1245 return Handle<Code>::null(); |
1263 } | 1246 } |
1264 | 1247 |
1265 if (!IsSuitableForOnStackReplacement(isolate, function, unoptimized)) { | 1248 if (IsSuitableForOnStackReplacement(isolate, function, unoptimized)) { |
1249 if (RecompileConcurrent(function, pc_offset)) return Handle<Code>::null(); | |
1250 } else { | |
1266 if (FLAG_trace_osr) { | 1251 if (FLAG_trace_osr) { |
1267 PrintF("[COSR - "); | 1252 PrintF("[COSR - "); |
1268 function->PrintName(); | 1253 function->PrintName(); |
1269 PrintF(" is unsuitable, restoring interrupt calls]\n"); | 1254 PrintF(" is unsuitable, restoring interrupt calls]\n"); |
1270 } | 1255 } |
1271 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); | |
1272 return Handle<Code>::null(); | |
1273 } | 1256 } |
1274 | 1257 |
1275 if (!RecompileConcurrent(function, pc_offset)) { | 1258 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); |
1276 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); | |
1277 } | |
1278 return Handle<Code>::null(); | 1259 return Handle<Code>::null(); |
1279 } | 1260 } |
1280 | 1261 |
1281 | 1262 |
1282 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, | 1263 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, |
1283 Handle<Script> script) { | 1264 Handle<Script> script) { |
1284 // Precondition: code has been parsed and scopes have been analyzed. | 1265 // Precondition: code has been parsed and scopes have been analyzed. |
1285 CompilationInfoWithZone info(script); | 1266 CompilationInfoWithZone info(script); |
1286 info.SetFunction(literal); | 1267 info.SetFunction(literal); |
1287 info.SetScope(literal->scope()); | 1268 info.SetScope(literal->scope()); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1441 AllowHandleDereference allow_deref; | 1422 AllowHandleDereference allow_deref; |
1442 bool tracing_on = info()->IsStub() | 1423 bool tracing_on = info()->IsStub() |
1443 ? FLAG_trace_hydrogen_stubs | 1424 ? FLAG_trace_hydrogen_stubs |
1444 : (FLAG_trace_hydrogen && | 1425 : (FLAG_trace_hydrogen && |
1445 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1426 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
1446 return (tracing_on && | 1427 return (tracing_on && |
1447 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1428 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
1448 } | 1429 } |
1449 | 1430 |
1450 } } // namespace v8::internal | 1431 } } // namespace v8::internal |
OLD | NEW |