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

Side by Side Diff: src/full-codegen.cc

Issue 13811014: Fix OSR for nested loops. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 7 years, 8 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
« no previous file with comments | « src/full-codegen.h ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 #endif 315 #endif
316 LOG_CODE_EVENT(isolate, 316 LOG_CODE_EVENT(isolate,
317 CodeStartLinePosInfoRecordEvent(masm.positions_recorder())); 317 CodeStartLinePosInfoRecordEvent(masm.positions_recorder()));
318 318
319 FullCodeGenerator cgen(&masm, info); 319 FullCodeGenerator cgen(&masm, info);
320 cgen.Generate(); 320 cgen.Generate();
321 if (cgen.HasStackOverflow()) { 321 if (cgen.HasStackOverflow()) {
322 ASSERT(!isolate->has_pending_exception()); 322 ASSERT(!isolate->has_pending_exception());
323 return false; 323 return false;
324 } 324 }
325 unsigned table_offset = cgen.EmitStackCheckTable(); 325 unsigned table_offset = cgen.EmitBackEdgeTable();
326 326
327 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION); 327 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
328 Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); 328 Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
329 code->set_optimizable(info->IsOptimizable() && 329 code->set_optimizable(info->IsOptimizable() &&
330 !info->function()->flags()->Contains(kDontOptimize) && 330 !info->function()->flags()->Contains(kDontOptimize) &&
331 info->function()->scope()->AllowsLazyCompilation()); 331 info->function()->scope()->AllowsLazyCompilation());
332 cgen.PopulateDeoptimizationData(code); 332 cgen.PopulateDeoptimizationData(code);
333 cgen.PopulateTypeFeedbackInfo(code); 333 cgen.PopulateTypeFeedbackInfo(code);
334 cgen.PopulateTypeFeedbackCells(code); 334 cgen.PopulateTypeFeedbackCells(code);
335 code->set_has_deoptimization_support(info->HasDeoptimizationSupport()); 335 code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
336 code->set_handler_table(*cgen.handler_table()); 336 code->set_handler_table(*cgen.handler_table());
337 #ifdef ENABLE_DEBUGGER_SUPPORT 337 #ifdef ENABLE_DEBUGGER_SUPPORT
338 code->set_has_debug_break_slots( 338 code->set_has_debug_break_slots(
339 info->isolate()->debugger()->IsDebuggerActive()); 339 info->isolate()->debugger()->IsDebuggerActive());
340 code->set_compiled_optimizable(info->IsOptimizable()); 340 code->set_compiled_optimizable(info->IsOptimizable());
341 #endif // ENABLE_DEBUGGER_SUPPORT 341 #endif // ENABLE_DEBUGGER_SUPPORT
342 code->set_allow_osr_at_loop_nesting_level(0); 342 code->set_allow_osr_at_loop_nesting_level(0);
343 code->set_profiler_ticks(0); 343 code->set_profiler_ticks(0);
344 code->set_stack_check_table_offset(table_offset); 344 code->set_back_edge_table_offset(table_offset);
345 code->set_stack_check_patched_for_osr(false); 345 code->set_back_edges_patched_for_osr(false);
346 CodeGenerator::PrintCode(code, info); 346 CodeGenerator::PrintCode(code, info);
347 info->SetCode(code); // May be an empty handle. 347 info->SetCode(code); // May be an empty handle.
348 #ifdef ENABLE_GDB_JIT_INTERFACE 348 #ifdef ENABLE_GDB_JIT_INTERFACE
349 if (FLAG_gdbjit && !code.is_null()) { 349 if (FLAG_gdbjit && !code.is_null()) {
350 GDBJITLineInfo* lineinfo = 350 GDBJITLineInfo* lineinfo =
351 masm.positions_recorder()->DetachGDBJITLineInfo(); 351 masm.positions_recorder()->DetachGDBJITLineInfo();
352 352
353 GDBJIT(RegisterDetailedLineInfo(*code, lineinfo)); 353 GDBJIT(RegisterDetailedLineInfo(*code, lineinfo));
354 } 354 }
355 #endif 355 #endif
356 if (!code.is_null()) { 356 if (!code.is_null()) {
357 void* line_info = 357 void* line_info =
358 masm.positions_recorder()->DetachJITHandlerData(); 358 masm.positions_recorder()->DetachJITHandlerData();
359 LOG_CODE_EVENT(isolate, CodeEndLinePosInfoRecordEvent(*code, line_info)); 359 LOG_CODE_EVENT(isolate, CodeEndLinePosInfoRecordEvent(*code, line_info));
360 } 360 }
361 return !code.is_null(); 361 return !code.is_null();
362 } 362 }
363 363
364 364
365 unsigned FullCodeGenerator::EmitStackCheckTable() { 365 unsigned FullCodeGenerator::EmitBackEdgeTable() {
366 // The stack check table consists of a length (in number of entries) 366 // The back edge table consists of a length (in number of entries)
367 // field, and then a sequence of entries. Each entry is a pair of AST id 367 // field, and then a sequence of entries. Each entry is a pair of AST id
368 // and code-relative pc offset. 368 // and code-relative pc offset.
369 masm()->Align(kIntSize); 369 masm()->Align(kIntSize);
370 unsigned offset = masm()->pc_offset(); 370 unsigned offset = masm()->pc_offset();
371 unsigned length = stack_checks_.length(); 371 unsigned length = back_edges_.length();
372 __ dd(length); 372 __ dd(length);
373 for (unsigned i = 0; i < length; ++i) { 373 for (unsigned i = 0; i < length; ++i) {
374 __ dd(stack_checks_[i].id.ToInt()); 374 __ dd(back_edges_[i].id.ToInt());
375 __ dd(stack_checks_[i].pc_and_state); 375 __ dd(back_edges_[i].pc);
376 __ db(back_edges_[i].loop_depth);
376 } 377 }
377 return offset; 378 return offset;
378 } 379 }
379 380
380 381
381 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { 382 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
382 // Fill in the deoptimization information. 383 // Fill in the deoptimization information.
383 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); 384 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
384 if (!info_->HasDeoptimizationSupport()) return; 385 if (!info_->HasDeoptimizationSupport()) return;
385 int length = bailout_entries_.length(); 386 int length = bailout_entries_.length();
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 void FullCodeGenerator::RecordTypeFeedbackCell( 472 void FullCodeGenerator::RecordTypeFeedbackCell(
472 TypeFeedbackId id, Handle<JSGlobalPropertyCell> cell) { 473 TypeFeedbackId id, Handle<JSGlobalPropertyCell> cell) {
473 TypeFeedbackCellEntry entry = { id, cell }; 474 TypeFeedbackCellEntry entry = { id, cell };
474 type_feedback_cells_.Add(entry, zone()); 475 type_feedback_cells_.Add(entry, zone());
475 } 476 }
476 477
477 478
478 void FullCodeGenerator::RecordBackEdge(BailoutId ast_id) { 479 void FullCodeGenerator::RecordBackEdge(BailoutId ast_id) {
479 // The pc offset does not need to be encoded and packed together with a state. 480 // The pc offset does not need to be encoded and packed together with a state.
480 ASSERT(masm_->pc_offset() > 0); 481 ASSERT(masm_->pc_offset() > 0);
481 BailoutEntry entry = { ast_id, static_cast<unsigned>(masm_->pc_offset()) }; 482 ASSERT(loop_depth() > 0);
482 stack_checks_.Add(entry, zone()); 483 uint8_t depth = Min(loop_depth(), Code::kMaxLoopNestingMarker);
484 BackEdgeEntry entry =
485 { ast_id, static_cast<unsigned>(masm_->pc_offset()), depth };
486 back_edges_.Add(entry, zone());
483 } 487 }
484 488
485 489
486 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { 490 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) {
487 // Inline smi case inside loops, but not division and modulo which 491 // Inline smi case inside loops, but not division and modulo which
488 // are too complicated and take up too much space. 492 // are too complicated and take up too much space.
489 if (op == Token::DIV ||op == Token::MOD) return false; 493 if (op == Token::DIV ||op == Token::MOD) return false;
490 if (FLAG_always_inline_smi_code) return true; 494 if (FLAG_always_inline_smi_code) return true;
491 return loop_depth_ > 0; 495 return loop_depth_ > 0;
492 } 496 }
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 // Pop context. 1248 // Pop context.
1245 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1249 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1246 // Update local stack frame context field. 1250 // Update local stack frame context field.
1247 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1251 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1248 } 1252 }
1249 1253
1250 1254
1251 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1255 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1252 Comment cmnt(masm_, "[ DoWhileStatement"); 1256 Comment cmnt(masm_, "[ DoWhileStatement");
1253 SetStatementPosition(stmt); 1257 SetStatementPosition(stmt);
1254 Label body, stack_check; 1258 Label body, book_keeping;
1255 1259
1256 Iteration loop_statement(this, stmt); 1260 Iteration loop_statement(this, stmt);
1257 increment_loop_depth(); 1261 increment_loop_depth();
1258 1262
1259 __ bind(&body); 1263 __ bind(&body);
1260 Visit(stmt->body()); 1264 Visit(stmt->body());
1261 1265
1262 // Record the position of the do while condition and make sure it is 1266 // Record the position of the do while condition and make sure it is
1263 // possible to break on the condition. 1267 // possible to break on the condition.
1264 __ bind(loop_statement.continue_label()); 1268 __ bind(loop_statement.continue_label());
1265 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1269 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1266 SetExpressionPosition(stmt->cond(), stmt->condition_position()); 1270 SetExpressionPosition(stmt->cond(), stmt->condition_position());
1267 VisitForControl(stmt->cond(), 1271 VisitForControl(stmt->cond(),
1268 &stack_check, 1272 &book_keeping,
1269 loop_statement.break_label(), 1273 loop_statement.break_label(),
1270 &stack_check); 1274 &book_keeping);
1271 1275
1272 // Check stack before looping. 1276 // Check stack before looping.
1273 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1277 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1274 __ bind(&stack_check); 1278 __ bind(&book_keeping);
1275 EmitBackEdgeBookkeeping(stmt, &body); 1279 EmitBackEdgeBookkeeping(stmt, &body);
1276 __ jmp(&body); 1280 __ jmp(&body);
1277 1281
1278 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1282 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1279 __ bind(loop_statement.break_label()); 1283 __ bind(loop_statement.break_label());
1280 decrement_loop_depth(); 1284 decrement_loop_depth();
1281 } 1285 }
1282 1286
1283 1287
1284 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1288 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 } 1608 }
1605 1609
1606 return false; 1610 return false;
1607 } 1611 }
1608 1612
1609 1613
1610 #undef __ 1614 #undef __
1611 1615
1612 1616
1613 } } // namespace v8::internal 1617 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698