| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 | 78 |
| 79 bool LCodeGen::GenerateCode() { | 79 bool LCodeGen::GenerateCode() { |
| 80 HPhase phase("Code generation", chunk()); | 80 HPhase phase("Code generation", chunk()); |
| 81 ASSERT(is_unused()); | 81 ASSERT(is_unused()); |
| 82 status_ = GENERATING; | 82 status_ = GENERATING; |
| 83 CpuFeatures::Scope scope1(VFP3); | 83 CpuFeatures::Scope scope1(VFP3); |
| 84 CpuFeatures::Scope scope2(ARMv7); | 84 CpuFeatures::Scope scope2(ARMv7); |
| 85 return GeneratePrologue() && | 85 return GeneratePrologue() && |
| 86 GenerateBody() && | 86 GenerateBody() && |
| 87 GenerateDeferredCode() && | 87 GenerateDeferredCode() && |
| 88 GenerateDeoptJumpTable() && |
| 88 GenerateSafepointTable(); | 89 GenerateSafepointTable(); |
| 89 } | 90 } |
| 90 | 91 |
| 91 | 92 |
| 92 void LCodeGen::FinishCode(Handle<Code> code) { | 93 void LCodeGen::FinishCode(Handle<Code> code) { |
| 93 ASSERT(is_done()); | 94 ASSERT(is_done()); |
| 94 code->set_stack_slots(GetStackSlotCount()); | 95 code->set_stack_slots(GetStackSlotCount()); |
| 95 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); | 96 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); |
| 96 PopulateDeoptimizationData(code); | 97 PopulateDeoptimizationData(code); |
| 97 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); | 98 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 | 243 |
| 243 bool LCodeGen::GenerateDeferredCode() { | 244 bool LCodeGen::GenerateDeferredCode() { |
| 244 ASSERT(is_generating()); | 245 ASSERT(is_generating()); |
| 245 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 246 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
| 246 LDeferredCode* code = deferred_[i]; | 247 LDeferredCode* code = deferred_[i]; |
| 247 __ bind(code->entry()); | 248 __ bind(code->entry()); |
| 248 code->Generate(); | 249 code->Generate(); |
| 249 __ jmp(code->exit()); | 250 __ jmp(code->exit()); |
| 250 } | 251 } |
| 251 | 252 |
| 252 // Force constant pool emission at the end of deferred code to make | 253 // Force constant pool emission at the end of the deferred code to make |
| 253 // sure that no constant pools are emitted after the official end of | 254 // sure that no constant pools are emitted after. |
| 254 // the instruction sequence. | |
| 255 masm()->CheckConstPool(true, false); | 255 masm()->CheckConstPool(true, false); |
| 256 | 256 |
| 257 // Deferred code is the last part of the instruction sequence. Mark | 257 return !is_aborted(); |
| 258 // the generated code as done unless we bailed out. | 258 } |
| 259 |
| 260 |
| 261 bool LCodeGen::GenerateDeoptJumpTable() { |
| 262 // Check that the jump table is accessible from everywhere in the function |
| 263 // code, ie that offsets to the table can be encoded in the 24bit signed |
| 264 // immediate of a branch instruction. |
| 265 // To simplify we consider the code size from the first instruction to the |
| 266 // end of the jump table. We also don't consider the pc load delta. |
| 267 // Each entry in the jump table generates one instruction and inlines one |
| 268 // 32bit data after it. |
| 269 if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) + |
| 270 deopt_jump_table_.length() * 2)) { |
| 271 Abort("Generated code is too large"); |
| 272 } |
| 273 |
| 274 // Block the constant pool emission during the jump table emission. |
| 275 __ BlockConstPoolFor(deopt_jump_table_.length()); |
| 276 __ RecordComment("[ Deoptimisation jump table"); |
| 277 Label table_start; |
| 278 __ bind(&table_start); |
| 279 for (int i = 0; i < deopt_jump_table_.length(); i++) { |
| 280 __ bind(&deopt_jump_table_[i].label); |
| 281 __ ldr(pc, MemOperand(pc, Assembler::kInstrSize - Assembler::kPcLoadDelta)); |
| 282 __ dd(reinterpret_cast<uint32_t>(deopt_jump_table_[i].address)); |
| 283 } |
| 284 ASSERT(masm()->InstructionsGeneratedSince(&table_start) == |
| 285 deopt_jump_table_.length() * 2); |
| 286 __ RecordComment("]"); |
| 287 |
| 288 // The deoptimization jump table is the last part of the instruction |
| 289 // sequence. Mark the generated code as done unless we bailed out. |
| 259 if (!is_aborted()) status_ = DONE; | 290 if (!is_aborted()) status_ = DONE; |
| 260 return !is_aborted(); | 291 return !is_aborted(); |
| 261 } | 292 } |
| 262 | 293 |
| 263 | 294 |
| 264 bool LCodeGen::GenerateSafepointTable() { | 295 bool LCodeGen::GenerateSafepointTable() { |
| 265 ASSERT(is_done()); | 296 ASSERT(is_done()); |
| 266 safepoints_.Emit(masm(), GetStackSlotCount()); | 297 safepoints_.Emit(masm(), GetStackSlotCount()); |
| 267 return !is_aborted(); | 298 return !is_aborted(); |
| 268 } | 299 } |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 } | 619 } |
| 589 | 620 |
| 590 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM. | 621 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM. |
| 591 | 622 |
| 592 if (FLAG_deopt_every_n_times == 1 && | 623 if (FLAG_deopt_every_n_times == 1 && |
| 593 info_->shared_info()->opt_count() == id) { | 624 info_->shared_info()->opt_count() == id) { |
| 594 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); | 625 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); |
| 595 return; | 626 return; |
| 596 } | 627 } |
| 597 | 628 |
| 629 if (FLAG_trap_on_deopt) __ stop("trap_on_deopt", cc); |
| 630 |
| 598 if (cc == al) { | 631 if (cc == al) { |
| 599 if (FLAG_trap_on_deopt) __ stop("trap_on_deopt"); | |
| 600 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); | 632 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); |
| 601 } else { | 633 } else { |
| 602 if (FLAG_trap_on_deopt) { | 634 // We often have several deopts to the same entry, reuse the last |
| 603 Label done; | 635 // jump entry if this is the case. |
| 604 __ b(&done, NegateCondition(cc)); | 636 if (deopt_jump_table_.is_empty() || |
| 605 __ stop("trap_on_deopt"); | 637 (deopt_jump_table_.last().address != entry)) { |
| 606 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); | 638 deopt_jump_table_.Add(JumpTableEntry(entry)); |
| 607 __ bind(&done); | |
| 608 } else { | |
| 609 __ Jump(entry, RelocInfo::RUNTIME_ENTRY, cc); | |
| 610 } | 639 } |
| 640 __ b(cc, &deopt_jump_table_.last().label); |
| 611 } | 641 } |
| 612 } | 642 } |
| 613 | 643 |
| 614 | 644 |
| 615 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { | 645 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { |
| 616 int length = deoptimizations_.length(); | 646 int length = deoptimizations_.length(); |
| 617 if (length == 0) return; | 647 if (length == 0) return; |
| 618 ASSERT(FLAG_deopt); | 648 ASSERT(FLAG_deopt); |
| 619 Handle<DeoptimizationInputData> data = | 649 Handle<DeoptimizationInputData> data = |
| 620 factory()->NewDeoptimizationInputData(length, TENURED); | 650 factory()->NewDeoptimizationInputData(length, TENURED); |
| (...skipping 3845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4466 ASSERT(osr_pc_offset_ == -1); | 4496 ASSERT(osr_pc_offset_ == -1); |
| 4467 osr_pc_offset_ = masm()->pc_offset(); | 4497 osr_pc_offset_ = masm()->pc_offset(); |
| 4468 } | 4498 } |
| 4469 | 4499 |
| 4470 | 4500 |
| 4471 | 4501 |
| 4472 | 4502 |
| 4473 #undef __ | 4503 #undef __ |
| 4474 | 4504 |
| 4475 } } // namespace v8::internal | 4505 } } // namespace v8::internal |
| OLD | NEW |