OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 | 294 |
295 bool LCodeGen::GenerateJumpTable() { | 295 bool LCodeGen::GenerateJumpTable() { |
296 Label needs_frame_not_call; | 296 Label needs_frame_not_call; |
297 Label needs_frame_is_call; | 297 Label needs_frame_is_call; |
298 if (jump_table_.length() > 0) { | 298 if (jump_table_.length() > 0) { |
299 Comment(";;; -------------------- Jump table --------------------"); | 299 Comment(";;; -------------------- Jump table --------------------"); |
300 } | 300 } |
301 for (int i = 0; i < jump_table_.length(); i++) { | 301 for (int i = 0; i < jump_table_.length(); i++) { |
302 __ bind(&jump_table_[i].label); | 302 __ bind(&jump_table_[i].label); |
303 Address entry = jump_table_[i].address; | 303 Address entry = jump_table_[i].address; |
304 bool is_lazy_deopt = jump_table_[i].is_lazy_deopt; | 304 Deoptimizer::BailoutType type = jump_table_[i].bailout_type; |
305 Deoptimizer::BailoutType type = | |
306 is_lazy_deopt ? Deoptimizer::LAZY : Deoptimizer::EAGER; | |
307 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); | 305 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); |
308 if (id == Deoptimizer::kNotDeoptimizationEntry) { | 306 if (id == Deoptimizer::kNotDeoptimizationEntry) { |
309 Comment(";;; jump table entry %d.", i); | 307 Comment(";;; jump table entry %d.", i); |
310 } else { | 308 } else { |
311 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); | 309 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); |
312 } | 310 } |
313 if (jump_table_[i].needs_frame) { | 311 if (jump_table_[i].needs_frame) { |
314 __ movq(kScratchRegister, ExternalReference::ForDeoptEntry(entry)); | 312 __ movq(kScratchRegister, ExternalReference::ForDeoptEntry(entry)); |
315 if (is_lazy_deopt) { | 313 if (type == Deoptimizer::LAZY) { |
316 if (needs_frame_is_call.is_bound()) { | 314 if (needs_frame_is_call.is_bound()) { |
317 __ jmp(&needs_frame_is_call); | 315 __ jmp(&needs_frame_is_call); |
318 } else { | 316 } else { |
319 __ bind(&needs_frame_is_call); | 317 __ bind(&needs_frame_is_call); |
320 __ push(rbp); | 318 __ push(rbp); |
321 __ movq(rbp, rsp); | 319 __ movq(rbp, rsp); |
322 __ push(rsi); | 320 __ push(rsi); |
323 // This variant of deopt can only be used with stubs. Since we don't | 321 // This variant of deopt can only be used with stubs. Since we don't |
324 // have a function pointer to install in the stack frame that we're | 322 // have a function pointer to install in the stack frame that we're |
325 // building, install a special marker there instead. | 323 // building, install a special marker there instead. |
(...skipping 15 matching lines...) Expand all Loading... |
341 // have a function pointer to install in the stack frame that we're | 339 // have a function pointer to install in the stack frame that we're |
342 // building, install a special marker there instead. | 340 // building, install a special marker there instead. |
343 ASSERT(info()->IsStub()); | 341 ASSERT(info()->IsStub()); |
344 __ Move(rsi, Smi::FromInt(StackFrame::STUB)); | 342 __ Move(rsi, Smi::FromInt(StackFrame::STUB)); |
345 __ push(rsi); | 343 __ push(rsi); |
346 __ movq(rsi, MemOperand(rsp, kPointerSize)); | 344 __ movq(rsi, MemOperand(rsp, kPointerSize)); |
347 __ jmp(kScratchRegister); | 345 __ jmp(kScratchRegister); |
348 } | 346 } |
349 } | 347 } |
350 } else { | 348 } else { |
351 if (is_lazy_deopt) { | 349 if (type == Deoptimizer::LAZY) { |
352 __ call(entry, RelocInfo::RUNTIME_ENTRY); | 350 __ call(entry, RelocInfo::RUNTIME_ENTRY); |
353 } else { | 351 } else { |
354 __ jmp(entry, RelocInfo::RUNTIME_ENTRY); | 352 __ jmp(entry, RelocInfo::RUNTIME_ENTRY); |
355 } | 353 } |
356 } | 354 } |
357 } | 355 } |
358 return !is_aborted(); | 356 return !is_aborted(); |
359 } | 357 } |
360 | 358 |
361 | 359 |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 int deoptimization_index = deoptimizations_.length(); | 710 int deoptimization_index = deoptimizations_.length(); |
713 int pc_offset = masm()->pc_offset(); | 711 int pc_offset = masm()->pc_offset(); |
714 environment->Register(deoptimization_index, | 712 environment->Register(deoptimization_index, |
715 translation.index(), | 713 translation.index(), |
716 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); | 714 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); |
717 deoptimizations_.Add(environment, environment->zone()); | 715 deoptimizations_.Add(environment, environment->zone()); |
718 } | 716 } |
719 } | 717 } |
720 | 718 |
721 | 719 |
722 void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) { | 720 void LCodeGen::DeoptimizeIf(Condition cc, |
| 721 LEnvironment* environment, |
| 722 Deoptimizer::BailoutType bailout_type) { |
723 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 723 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
724 ASSERT(environment->HasBeenRegistered()); | 724 ASSERT(environment->HasBeenRegistered()); |
725 int id = environment->deoptimization_index(); | 725 int id = environment->deoptimization_index(); |
726 ASSERT(info()->IsOptimizing() || info()->IsStub()); | 726 ASSERT(info()->IsOptimizing() || info()->IsStub()); |
727 Deoptimizer::BailoutType bailout_type = info()->IsStub() | |
728 ? Deoptimizer::LAZY | |
729 : Deoptimizer::EAGER; | |
730 Address entry = | 727 Address entry = |
731 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); | 728 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); |
732 if (entry == NULL) { | 729 if (entry == NULL) { |
733 Abort("bailout was not prepared"); | 730 Abort("bailout was not prepared"); |
734 return; | 731 return; |
735 } | 732 } |
736 | 733 |
737 ASSERT(FLAG_deopt_every_n_times == 0); // Not yet implemented on x64. | 734 ASSERT(FLAG_deopt_every_n_times == 0); // Not yet implemented on x64. |
738 | 735 |
739 if (FLAG_trap_on_deopt) { | 736 if (FLAG_trap_on_deopt) { |
(...skipping 12 matching lines...) Expand all Loading... |
752 __ call(entry, RelocInfo::RUNTIME_ENTRY); | 749 __ call(entry, RelocInfo::RUNTIME_ENTRY); |
753 } else { | 750 } else { |
754 __ jmp(entry, RelocInfo::RUNTIME_ENTRY); | 751 __ jmp(entry, RelocInfo::RUNTIME_ENTRY); |
755 } | 752 } |
756 } else { | 753 } else { |
757 // We often have several deopts to the same entry, reuse the last | 754 // We often have several deopts to the same entry, reuse the last |
758 // jump entry if this is the case. | 755 // jump entry if this is the case. |
759 if (jump_table_.is_empty() || | 756 if (jump_table_.is_empty() || |
760 jump_table_.last().address != entry || | 757 jump_table_.last().address != entry || |
761 jump_table_.last().needs_frame != !frame_is_built_ || | 758 jump_table_.last().needs_frame != !frame_is_built_ || |
762 jump_table_.last().is_lazy_deopt != needs_lazy_deopt) { | 759 jump_table_.last().bailout_type != bailout_type) { |
763 JumpTableEntry table_entry(entry, !frame_is_built_, needs_lazy_deopt); | 760 Deoptimizer::JumpTableEntry table_entry(entry, |
| 761 bailout_type, |
| 762 !frame_is_built_); |
764 jump_table_.Add(table_entry, zone()); | 763 jump_table_.Add(table_entry, zone()); |
765 } | 764 } |
766 if (cc == no_condition) { | 765 if (cc == no_condition) { |
767 __ jmp(&jump_table_.last().label); | 766 __ jmp(&jump_table_.last().label); |
768 } else { | 767 } else { |
769 __ j(cc, &jump_table_.last().label); | 768 __ j(cc, &jump_table_.last().label); |
770 } | 769 } |
771 } | 770 } |
772 } | 771 } |
773 | 772 |
774 | 773 |
| 774 void LCodeGen::DeoptimizeIf(Condition cc, |
| 775 LEnvironment* environment) { |
| 776 Deoptimizer::BailoutType bailout_type = info()->IsStub() |
| 777 ? Deoptimizer::LAZY |
| 778 : Deoptimizer::EAGER; |
| 779 DeoptimizeIf(cc, environment, bailout_type); |
| 780 } |
| 781 |
| 782 |
| 783 void LCodeGen::SoftDeoptimize(LEnvironment* environment) { |
| 784 ASSERT(!info()->IsStub()); |
| 785 DeoptimizeIf(no_condition, environment, Deoptimizer::SOFT); |
| 786 } |
| 787 |
| 788 |
775 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { | 789 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { |
776 ZoneList<Handle<Map> > maps(1, zone()); | 790 ZoneList<Handle<Map> > maps(1, zone()); |
777 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 791 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
778 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { | 792 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { |
779 RelocInfo::Mode mode = it.rinfo()->rmode(); | 793 RelocInfo::Mode mode = it.rinfo()->rmode(); |
780 if (mode == RelocInfo::EMBEDDED_OBJECT && | 794 if (mode == RelocInfo::EMBEDDED_OBJECT && |
781 it.rinfo()->target_object()->IsMap()) { | 795 it.rinfo()->target_object()->IsMap()) { |
782 Handle<Map> map(Map::cast(it.rinfo()->target_object())); | 796 Handle<Map> map(Map::cast(it.rinfo()->target_object())); |
783 if (map->CanTransition()) { | 797 if (map->CanTransition()) { |
784 maps.Add(map, zone()); | 798 maps.Add(map, zone()); |
(...skipping 4622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5407 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); | 5421 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); |
5408 last_lazy_deopt_pc_ = masm()->pc_offset(); | 5422 last_lazy_deopt_pc_ = masm()->pc_offset(); |
5409 ASSERT(instr->HasEnvironment()); | 5423 ASSERT(instr->HasEnvironment()); |
5410 LEnvironment* env = instr->environment(); | 5424 LEnvironment* env = instr->environment(); |
5411 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); | 5425 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); |
5412 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 5426 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
5413 } | 5427 } |
5414 | 5428 |
5415 | 5429 |
5416 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { | 5430 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { |
5417 DeoptimizeIf(no_condition, instr->environment()); | 5431 if (instr->hydrogen_value()->IsSoftDeoptimize()) { |
| 5432 SoftDeoptimize(instr->environment()); |
| 5433 } else { |
| 5434 DeoptimizeIf(no_condition, instr->environment()); |
| 5435 } |
5418 } | 5436 } |
5419 | 5437 |
5420 | 5438 |
5421 void LCodeGen::DoDummyUse(LDummyUse* instr) { | 5439 void LCodeGen::DoDummyUse(LDummyUse* instr) { |
5422 // Nothing to see here, move on! | 5440 // Nothing to see here, move on! |
5423 } | 5441 } |
5424 | 5442 |
5425 | 5443 |
5426 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { | 5444 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { |
5427 LOperand* obj = instr->object(); | 5445 LOperand* obj = instr->object(); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5616 FixedArray::kHeaderSize - kPointerSize)); | 5634 FixedArray::kHeaderSize - kPointerSize)); |
5617 __ bind(&done); | 5635 __ bind(&done); |
5618 } | 5636 } |
5619 | 5637 |
5620 | 5638 |
5621 #undef __ | 5639 #undef __ |
5622 | 5640 |
5623 } } // namespace v8::internal | 5641 } } // namespace v8::internal |
5624 | 5642 |
5625 #endif // V8_TARGET_ARCH_X64 | 5643 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |