Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(728)

Side by Side Diff: src/compiler.cc

Issue 23842004: Pass PC offset into runtime when compiling for OSR. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 } 1113 }
1114 // Optimized code is finally replacing unoptimized code. Reset the latter's 1114 // Optimized code is finally replacing unoptimized code. Reset the latter's
1115 // profiler ticks to prevent too soon re-opt after a deopt. 1115 // profiler ticks to prevent too soon re-opt after a deopt.
1116 info->shared_info()->code()->set_profiler_ticks(0); 1116 info->shared_info()->code()->set_profiler_ticks(0);
1117 ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode()); 1117 ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode());
1118 return (status == OptimizingCompiler::SUCCEEDED) ? info->code() 1118 return (status == OptimizingCompiler::SUCCEEDED) ? info->code()
1119 : Handle<Code>::null(); 1119 : Handle<Code>::null();
1120 } 1120 }
1121 1121
1122 1122
1123 static uint32_t CurrentPcOffset(Isolate* isolate,
1124 Handle<JSFunction> function,
1125 Handle<Code> unoptimized) {
1126 JavaScriptFrameIterator it(isolate);
1127 JavaScriptFrame* frame = it.frame();
1128 ASSERT(frame->function() == *function);
1129 ASSERT(frame->LookupCode() == *unoptimized);
1130 ASSERT(unoptimized->contains(frame->pc()));
1131
1132 // Use linear search of the unoptimized code's back edge table to find
1133 // the AST id matching the PC.
1134 return static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start());
1135 }
1136
1137
1138 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
1139 Handle<JSFunction> function,
1140 Handle<Code> unoptimized) {
1141 // Keep track of whether we've succeeded in optimizing.
1142 if (!unoptimized->optimizable()) return false;
1143 // If we are trying to do OSR when there are already optimized
1144 // activations of the function, it means (a) the function is directly or
1145 // indirectly recursive and (b) an optimized invocation has been
1146 // deoptimized so that we are currently in an unoptimized activation.
1147 // Check for optimized activations of this function.
1148 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
1149 JavaScriptFrame* frame = it.frame();
1150 if (frame->is_optimized() && frame->function() == *function) return false;
1151 }
1152
1153 return true;
1154 }
1155
1156
1157 Handle<Code> Compiler::CompileForOnStackReplacement(
1158 Handle<JSFunction> function) {
1159 Isolate* isolate = function->GetIsolate();
1160 Handle<Code> unoptimized(function->shared()->code(), isolate);
1161
1162 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1163 if (FLAG_trace_osr) {
1164 PrintF("[OSR - restored original interrupt calls in ");
1165 function->PrintName();
1166 PrintF("]\n");
1167 }
1168
1169 if (IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
1170 // Find the PC offset in unoptimized code and translate to an AST id.
1171 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized);
1172 BailoutId ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset);
1173 ASSERT(!ast_id.IsNone());
1174 if (FLAG_trace_osr) {
1175 PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt());
1176 function->PrintName();
1177 PrintF("]\n");
1178 }
1179
1180 // Attempt OSR compilation.
1181 Handle<Code> result = JSFunction::CompileOsr(
1182 function, ast_id, CLEAR_EXCEPTION);
1183
1184 if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
1185 // OSR compilation succeeded.
1186 DeoptimizationInputData* data =
1187 DeoptimizationInputData::cast(result->deoptimization_data());
1188 if (FLAG_trace_osr) {
1189 PrintF("[OSR - entry, offset %d in optimized code]\n",
1190 data->OsrPcOffset()->value());
1191 }
1192 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
1193 return result;
1194 }
1195 }
1196
1197 if (FLAG_trace_osr) {
1198 PrintF("[OSR - attempt failed for ");
1199 function->PrintName();
1200 PrintF("]\n");
1201 }
1202 return Handle<Code>::null();
1203 }
1204
1205
1206 Handle<Code> Compiler::CompileForConcurrentOSR(Handle<JSFunction> function) {
1207 Isolate* isolate = function->GetIsolate();
1208 Handle<Code> unoptimized(function->shared()->code(), isolate);
1209
1210 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized);
1211
1212 if (isolate->optimizing_compiler_thread()->
1213 IsQueuedForOSR(function, pc_offset)) {
1214 // Still waiting for the optimizing compiler thread to finish. Carry on.
1215 if (FLAG_trace_osr) {
1216 PrintF("[COSR - polling recompile tasks for ");
1217 function->PrintName();
1218 PrintF("]\n");
1219 }
1220 return Handle<Code>::null();
1221 }
1222
1223 OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()->
1224 FindReadyOSRCandidate(function, pc_offset);
1225
1226 if (compiler != NULL) {
1227 BailoutId ast_id = compiler->info()->osr_ast_id();
1228
1229 if (FLAG_trace_osr) {
1230 PrintF("[COSR - optimization complete for ");
1231 function->PrintName();
1232 PrintF(", restoring interrupt calls]\n");
1233 }
1234 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1235
1236 // TODO(titzer): don't install the OSR code into the function.
1237 Handle<Code> result = InstallOptimizedCode(compiler);
1238
1239 isolate->optimizing_compiler_thread()->RemoveStaleOSRCandidates();
1240
1241 if (result.is_null()) {
1242 if (FLAG_trace_osr) {
1243 PrintF("[COSR - optimization failed for ");
1244 function->PrintName();
1245 PrintF("]\n");
1246 }
1247 return Handle<Code>::null();
1248 }
1249 // Check the result matches our expectations, and don't use it otherwise.
1250 if (result->kind() == Code::OPTIMIZED_FUNCTION) {
1251 DeoptimizationInputData* data =
1252 DeoptimizationInputData::cast(result->deoptimization_data());
1253
1254 if (data->OsrPcOffset()->value() >= 0) {
1255 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
1256 if (FLAG_trace_osr) {
1257 PrintF("[COSR - entry at AST id %d, offset %d in optimized code]\n",
1258 ast_id.ToInt(), data->OsrPcOffset()->value());
1259 }
1260 return result;
1261 }
1262 }
1263 return Handle<Code>::null();
1264 }
1265
1266 if (!IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
1267 if (FLAG_trace_osr) {
1268 PrintF("[COSR - ");
1269 function->PrintName();
1270 PrintF(" is unsuitable, restoring interrupt calls]\n");
1271 }
1272 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1273 return Handle<Code>::null();
1274 }
1275
1276 if (!RecompileConcurrent(function, pc_offset)) {
1277 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1278 }
1279 return Handle<Code>::null();
1280 }
1281
1282
1283 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, 1123 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
1284 Handle<Script> script) { 1124 Handle<Script> script) {
1285 // Precondition: code has been parsed and scopes have been analyzed. 1125 // Precondition: code has been parsed and scopes have been analyzed.
1286 CompilationInfoWithZone info(script); 1126 CompilationInfoWithZone info(script);
1287 info.SetFunction(literal); 1127 info.SetFunction(literal);
1288 info.SetScope(literal->scope()); 1128 info.SetScope(literal->scope());
1289 info.SetLanguageMode(literal->scope()->language_mode()); 1129 info.SetLanguageMode(literal->scope()->language_mode());
1290 1130
1291 Isolate* isolate = info.isolate(); 1131 Isolate* isolate = info.isolate();
1292 Factory* factory = isolate->factory(); 1132 Factory* factory = isolate->factory();
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 AllowHandleDereference allow_deref; 1282 AllowHandleDereference allow_deref;
1443 bool tracing_on = info()->IsStub() 1283 bool tracing_on = info()->IsStub()
1444 ? FLAG_trace_hydrogen_stubs 1284 ? FLAG_trace_hydrogen_stubs
1445 : (FLAG_trace_hydrogen && 1285 : (FLAG_trace_hydrogen &&
1446 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); 1286 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter));
1447 return (tracing_on && 1287 return (tracing_on &&
1448 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); 1288 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL);
1449 } 1289 }
1450 1290
1451 } } // namespace v8::internal 1291 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/ia32/builtins-ia32.cc » ('j') | src/runtime-profiler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698