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 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 stack check 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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |