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

Side by Side Diff: src/compiler.cc

Issue 21340002: Generate a custom OSR entrypoint for OSR compiles on all platforms, and transition to optimized cod… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remerge with recent changes. 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 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 // The encoding is as a signed value, with parameters and receiver using 351 // The encoding is as a signed value, with parameters and receiver using
352 // the negative indices and locals the non-negative ones. 352 // the negative indices and locals the non-negative ones.
353 const int parameter_limit = -LUnallocated::kMinFixedSlotIndex; 353 const int parameter_limit = -LUnallocated::kMinFixedSlotIndex;
354 Scope* scope = info()->scope(); 354 Scope* scope = info()->scope();
355 if ((scope->num_parameters() + 1) > parameter_limit) { 355 if ((scope->num_parameters() + 1) > parameter_limit) {
356 info()->set_bailout_reason(kTooManyParameters); 356 info()->set_bailout_reason(kTooManyParameters);
357 return AbortOptimization(); 357 return AbortOptimization();
358 } 358 }
359 359
360 const int locals_limit = LUnallocated::kMaxFixedSlotIndex; 360 const int locals_limit = LUnallocated::kMaxFixedSlotIndex;
361 if (!info()->osr_ast_id().IsNone() && 361 if (info()->is_osr() &&
362 scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit) { 362 scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit) {
363 info()->set_bailout_reason(kTooManyParametersLocals); 363 info()->set_bailout_reason(kTooManyParametersLocals);
364 return AbortOptimization(); 364 return AbortOptimization();
365 } 365 }
366 366
367 // Take --hydrogen-filter into account. 367 // Take --hydrogen-filter into account.
368 if (!info()->closure()->PassesFilter(FLAG_hydrogen_filter)) { 368 if (!info()->closure()->PassesFilter(FLAG_hydrogen_filter)) {
369 info()->AbortOptimization(); 369 info()->AbortOptimization();
370 return SetLastStatus(BAILED_OUT); 370 return SetLastStatus(BAILED_OUT);
371 } 371 }
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 } 877 }
878 Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); 878 Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
879 } 879 }
880 880
881 881
882 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { 882 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
883 Handle<Code> code = info->code(); 883 Handle<Code> code = info->code();
884 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. 884 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do.
885 885
886 // Cache non-OSR optimized code. 886 // Cache non-OSR optimized code.
887 if (FLAG_cache_optimized_code && info->osr_ast_id().IsNone()) { 887 if (FLAG_cache_optimized_code && !info->is_osr()) {
888 Handle<JSFunction> function = info->closure(); 888 Handle<JSFunction> function = info->closure();
889 Handle<SharedFunctionInfo> shared(function->shared()); 889 Handle<SharedFunctionInfo> shared(function->shared());
890 Handle<FixedArray> literals(function->literals()); 890 Handle<FixedArray> literals(function->literals());
891 Handle<Context> native_context(function->context()->native_context()); 891 Handle<Context> native_context(function->context()->native_context());
892 SharedFunctionInfo::AddToOptimizedCodeMap( 892 SharedFunctionInfo::AddToOptimizedCodeMap(
893 shared, native_context, code, literals); 893 shared, native_context, code, literals);
894 } 894 }
895 } 895 }
896 896
897 897
898 static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) { 898 static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) {
899 if (!info->IsOptimizing()) return false; // Nothing to look up. 899 if (!info->IsOptimizing()) return false; // Nothing to look up.
900 900
901 // Lookup non-OSR optimized code. 901 // Lookup non-OSR optimized code.
902 if (FLAG_cache_optimized_code && info->osr_ast_id().IsNone()) { 902 if (FLAG_cache_optimized_code && !info->is_osr()) {
903 Handle<SharedFunctionInfo> shared = info->shared_info(); 903 Handle<SharedFunctionInfo> shared = info->shared_info();
904 Handle<JSFunction> function = info->closure(); 904 Handle<JSFunction> function = info->closure();
905 ASSERT(!function.is_null()); 905 ASSERT(!function.is_null());
906 Handle<Context> native_context(function->context()->native_context()); 906 Handle<Context> native_context(function->context()->native_context());
907 int index = shared->SearchOptimizedCodeMap(*native_context); 907 int index = shared->SearchOptimizedCodeMap(*native_context);
908 if (index > 0) { 908 if (index > 0) {
909 if (FLAG_trace_opt) { 909 if (FLAG_trace_opt) {
910 PrintF("[found optimized code for "); 910 PrintF("[found optimized code for ");
911 function->ShortPrint(); 911 function->ShortPrint();
912 PrintF("]\n"); 912 PrintF("]\n");
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 948
949 // Compile the code. 949 // Compile the code.
950 if (!MakeCode(info)) { 950 if (!MakeCode(info)) {
951 if (!isolate->has_pending_exception()) { 951 if (!isolate->has_pending_exception()) {
952 isolate->StackOverflow(); 952 isolate->StackOverflow();
953 } 953 }
954 } else { 954 } else {
955 InstallCodeCommon(info); 955 InstallCodeCommon(info);
956 956
957 if (info->IsOptimizing()) { 957 if (info->IsOptimizing()) {
958 // Optimized code successfully created.
958 Handle<Code> code = info->code(); 959 Handle<Code> code = info->code();
959 ASSERT(shared->scope_info() != ScopeInfo::Empty(isolate)); 960 ASSERT(shared->scope_info() != ScopeInfo::Empty(isolate));
961 // TODO(titzer): Only replace the code if it was not an OSR compile.
960 info->closure()->ReplaceCode(*code); 962 info->closure()->ReplaceCode(*code);
961 InsertCodeIntoOptimizedCodeMap(info); 963 InsertCodeIntoOptimizedCodeMap(info);
962 return true; 964 return true;
963 } else { 965 } else if (!info->is_osr()) {
966 // Compilation failed. Replace with full code if not OSR compile.
964 return InstallFullCode(info); 967 return InstallFullCode(info);
965 } 968 }
966 } 969 }
967 } 970 }
968 971
969 ASSERT(info->code().is_null()); 972 ASSERT(info->code().is_null());
970 return false; 973 return false;
971 } 974 }
972 975
973 976
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 // Check for optimized activations of this function. 1145 // Check for optimized activations of this function.
1143 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { 1146 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
1144 JavaScriptFrame* frame = it.frame(); 1147 JavaScriptFrame* frame = it.frame();
1145 if (frame->is_optimized() && frame->function() == *function) return false; 1148 if (frame->is_optimized() && frame->function() == *function) return false;
1146 } 1149 }
1147 1150
1148 return true; 1151 return true;
1149 } 1152 }
1150 1153
1151 1154
1152 BailoutId Compiler::CompileForOnStackReplacement(Handle<JSFunction> function) { 1155 Handle<Code> Compiler::CompileForOnStackReplacement(
1156 Handle<JSFunction> function) {
1153 Isolate* isolate = function->GetIsolate(); 1157 Isolate* isolate = function->GetIsolate();
1154 // We have hit a back edge in an unoptimized frame for a function that was
1155 // selected for on-stack replacement. Find the unoptimized code object.
1156 Handle<Code> unoptimized(function->shared()->code(), isolate); 1158 Handle<Code> unoptimized(function->shared()->code(), isolate);
1157 1159
1158 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); 1160 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1159 if (FLAG_trace_osr) { 1161 if (FLAG_trace_osr) {
1160 PrintF("[OSR - restored original interrupt calls in "); 1162 PrintF("[OSR - restored original interrupt calls in ");
1161 function->PrintName(); 1163 function->PrintName();
1162 PrintF("]\n"); 1164 PrintF("]\n");
1163 } 1165 }
1164 1166
1165 if (!IsSuitableForOnStackReplacement(isolate, function, unoptimized)) { 1167 if (IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
1166 return BailoutId::None(); 1168 // Find the PC offset in unoptimized code and translate to an AST id.
1167 } 1169 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized);
1170 BailoutId ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset);
1171 ASSERT(!ast_id.IsNone());
1172 if (FLAG_trace_osr) {
1173 PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt());
1174 function->PrintName();
1175 PrintF("]\n");
1176 }
1168 1177
1169 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized); 1178 // Attempt OSR compilation.
1179 Handle<Code> result = JSFunction::CompileOsr(
1180 function, ast_id, CLEAR_EXCEPTION);
1170 1181
1171 BailoutId ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset); 1182 if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
1172 ASSERT(!ast_id.IsNone()); 1183 // OSR compilation succeeded.
1173 if (FLAG_trace_osr) { 1184 DeoptimizationInputData* data =
1174 PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt()); 1185 DeoptimizationInputData::cast(result->deoptimization_data());
1175 function->PrintName();
1176 PrintF("]\n");
1177 }
1178
1179 // Try to compile the optimized code. A true return value from
1180 // CompileOptimized means that compilation succeeded, not necessarily
1181 // that optimization succeeded.
1182 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
1183 function->IsOptimized()) {
1184 DeoptimizationInputData* data = DeoptimizationInputData::cast(
1185 function->code()->deoptimization_data());
1186 if (data->OsrPcOffset()->value() >= 0) {
1187 if (FLAG_trace_osr) { 1186 if (FLAG_trace_osr) {
1188 PrintF("[OSR - entry, offset %d in optimized code]\n", 1187 PrintF("[OSR - entry, offset %d in optimized code]\n",
1189 data->OsrPcOffset()->value()); 1188 data->OsrPcOffset()->value());
1190 } 1189 }
1191 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id); 1190 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
1192 return ast_id; 1191 return result;
1193 }
1194 } else {
1195 if (FLAG_trace_osr) {
1196 PrintF("[OSR - optimization failed for ");
1197 function->PrintName();
1198 PrintF("]\n");
1199 } 1192 }
1200 } 1193 }
1201 return BailoutId::None(); 1194
1195 if (FLAG_trace_osr) {
1196 PrintF("[OSR - attempt failed for ");
1197 function->PrintName();
1198 PrintF("]\n");
1199 }
1200 return Handle<Code>::null();
1202 } 1201 }
1203 1202
1204 1203
1205 BailoutId Compiler::CompileForConcurrentOSR(Handle<JSFunction> function) { 1204 Handle<Code> Compiler::CompileForConcurrentOSR(Handle<JSFunction> function) {
1206 Isolate* isolate = function->GetIsolate(); 1205 Isolate* isolate = function->GetIsolate();
1207 Handle<Code> unoptimized(function->shared()->code(), isolate); 1206 Handle<Code> unoptimized(function->shared()->code(), isolate);
1207 Handle<Code> result = Handle<Code>::null();
1208 1208
1209 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized); 1209 uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized);
1210 1210
1211 if (isolate->optimizing_compiler_thread()-> 1211 if (isolate->optimizing_compiler_thread()->
1212 IsQueuedForOSR(function, pc_offset)) { 1212 IsQueuedForOSR(function, pc_offset)) {
1213 // Still waiting for the optimizing compiler thread to finish. Carry on. 1213 // Still waiting for the optimizing compiler thread to finish. Carry on.
1214 if (FLAG_trace_osr) { 1214 if (FLAG_trace_osr) {
1215 PrintF("[COSR - polling recompile tasks for "); 1215 PrintF("[COSR - polling recompile tasks for ");
1216 function->PrintName(); 1216 function->PrintName();
1217 PrintF("]\n"); 1217 PrintF("]\n");
1218 } 1218 }
1219 return BailoutId::None(); 1219 return result; // return null.
Michael Starzinger 2013/09/09 15:34:44 nit: Can we just write down "Handle<Code>::null()"
1220 } 1220 }
1221 1221
1222 OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()-> 1222 OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()->
1223 FindReadyOSRCandidate(function, pc_offset); 1223 FindReadyOSRCandidate(function, pc_offset);
1224 1224
1225 if (compiler != NULL) { 1225 if (compiler != NULL) {
1226 if (FLAG_trace_osr) { 1226 if (FLAG_trace_osr) {
1227 PrintF("[COSR - optimization complete for "); 1227 PrintF("[COSR - optimization complete for ");
1228 function->PrintName(); 1228 function->PrintName();
1229 PrintF(", restoring interrupt calls]\n"); 1229 PrintF(", restoring interrupt calls]\n");
1230 } 1230 }
1231 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); 1231 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1232 1232
1233 BailoutId ast_id = compiler->info()->osr_ast_id(); 1233 // TODO(titzer): don't install the OSR code into the function.
1234
1235 bool succeeded = InstallOptimizedCode(compiler); 1234 bool succeeded = InstallOptimizedCode(compiler);
1236 1235
1237 isolate->optimizing_compiler_thread()->RemoveStaleOSRCandidates(); 1236 isolate->optimizing_compiler_thread()->RemoveStaleOSRCandidates();
1238 1237
1239 if (!succeeded) { 1238 if (!succeeded) {
1240 if (FLAG_trace_osr) { 1239 if (FLAG_trace_osr) {
1241 PrintF("[COSR - optimization failed for "); 1240 PrintF("[COSR - optimization failed for ");
1242 function->PrintName(); 1241 function->PrintName();
1243 PrintF("]\n"); 1242 PrintF("]\n");
1244 } 1243 }
1245 return BailoutId::None(); 1244 return result;
Michael Starzinger 2013/09/09 15:34:44 Likewise.
1246 } 1245 }
1246 result = compiler->info()->code();
1247 1247
1248 DeoptimizationInputData* data = DeoptimizationInputData::cast( 1248 // Check the result matches our expectations, and don't use it otherwise.
1249 function->code()->deoptimization_data()); 1249 if (result->kind() == Code::OPTIMIZED_FUNCTION) {
1250 DeoptimizationInputData* data =
1251 DeoptimizationInputData::cast(result->deoptimization_data());
1250 1252
1251 if (data->OsrPcOffset()->value() >= 0) { 1253 if (data->OsrPcOffset()->value() >= 0) {
1252 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id); 1254 BailoutId ast_id = compiler->info()->osr_ast_id();
1253 if (FLAG_trace_osr) { 1255 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
1254 PrintF("[COSR - entry at AST id %d, offset %d in optimized code]\n", 1256 if (FLAG_trace_osr) {
1255 ast_id.ToInt(), data->OsrPcOffset()->value()); 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;
1256 } 1261 }
1257 return ast_id;
1258 } 1262 }
1259 return BailoutId::None(); 1263 return Handle<Code>::null();
1260 } 1264 }
1261 1265
1262 if (!IsSuitableForOnStackReplacement(isolate, function, unoptimized)) { 1266 if (!IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
1263 if (FLAG_trace_osr) { 1267 if (FLAG_trace_osr) {
1264 PrintF("[COSR - "); 1268 PrintF("[COSR - ");
1265 function->PrintName(); 1269 function->PrintName();
1266 PrintF(" is unsuitable, restoring interrupt calls]\n"); 1270 PrintF(" is unsuitable, restoring interrupt calls]\n");
1267 } 1271 }
1268 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); 1272 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1269 return BailoutId::None(); 1273 return Handle<Code>::null();
1270 } 1274 }
1271 1275
1272 if (!RecompileConcurrent(function, pc_offset)) { 1276 if (!RecompileConcurrent(function, pc_offset)) {
1273 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); 1277 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
1274 } 1278 }
1275 return BailoutId::None(); 1279 return Handle<Code>::null();
1276 } 1280 }
1277 1281
1278 1282
1279 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, 1283 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
1280 Handle<Script> script) { 1284 Handle<Script> script) {
1281 // Precondition: code has been parsed and scopes have been analyzed. 1285 // Precondition: code has been parsed and scopes have been analyzed.
1282 CompilationInfoWithZone info(script); 1286 CompilationInfoWithZone info(script);
1283 info.SetFunction(literal); 1287 info.SetFunction(literal);
1284 info.SetScope(literal->scope()); 1288 info.SetScope(literal->scope());
1285 info.SetLanguageMode(literal->scope()->language_mode()); 1289 info.SetLanguageMode(literal->scope()->language_mode());
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 AllowHandleDereference allow_deref; 1442 AllowHandleDereference allow_deref;
1439 bool tracing_on = info()->IsStub() 1443 bool tracing_on = info()->IsStub()
1440 ? FLAG_trace_hydrogen_stubs 1444 ? FLAG_trace_hydrogen_stubs
1441 : (FLAG_trace_hydrogen && 1445 : (FLAG_trace_hydrogen &&
1442 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); 1446 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter));
1443 return (tracing_on && 1447 return (tracing_on &&
1444 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); 1448 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL);
1445 } 1449 }
1446 1450
1447 } } // namespace v8::internal 1451 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/deoptimizer.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698